对于那些想在第一次运行时使用数百万条记录初始化PostgreSQL DB的人。
使用*.sql dump导入
您可以进行简单的sql dump并将dump.sql
文件复制到/docker-entrypoint-initdb.d/
。问题在于速度。我的dump.sql
脚本约为17MB(小型DB-10个表,其中一个表中有100k行),初始化需要超过一分钟!这对于本地开发/单元测试等是不可接受的。
使用二进制转储进行导入
解决方案是制作二进制PostgreSQL转储并使用shell脚本初始化支持。
然后同样的DB只需用500毫秒进行初始化,而不是1分钟。
1.从容器内部或本地DB直接创建名为“my-db”的DB的dump.pgdata
二进制转储
pg_dump -U postgres --format custom my-db > "dump.pgdata"
或者从运行容器(postgres-container)的主机中获取
docker exec postgres-container pg_dump -U postgres --format custom my-db > "dump.pgdata"
2. 使用给定的转储和初始化脚本创建Docker镜像
$ tree
.
├── Dockerfile
└── docker-entrypoint-initdb.d
├── 01-restore.sh
├── 02-small-updates.sql
└── dump.pgdata
$ cat Dockerfile
FROM postgres:11
COPY ./docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
$ cat docker-entrypoint-initdb.d/01-restore.sh
file="/docker-entrypoint-initdb.d/dump.pgdata"
dbname=my-db
echo "Restoring DB using $file"
pg_restore -U postgres --dbname=$dbname --verbose --single-transaction < "$file" || exit 1
$ cat docker-entrypoint-initdb.d/02-small-updates.sql
UPDATE ... ;
3. 构建镜像并运行
$ docker build -t db-test-img .
$ docker run -it --rm --name db-test db-test-img
docker exec -it container psql –U postgres postgres < /dump/dump.sql
命令,即使这不是一个完美的解决方案,使用 supervisor 似乎有些过度(http://docs.docker.com/articles/using_supervisord/)。 - user2915097postgres --single
通常在转储文件中会失败。这是因为它将每一行解析为单独的 SQL 语句,或者将整个文件解析为一个语句,而这些都不适用于真正的转储。请参阅 postgres manpage。 - Daniel Vérité