暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用 Docker 搭建 PostgreSQL 12 主从环境

dotnet 新征程 2021-05-25
1428

环境准备:一台安装了Docker的Linux服务器。

为了简化演示环境,这里只用一台服务器来演示,通过不同端口来区分。


01


创建一个docker bridge 网路用于测试

    docker network create --subnet=172.18.0.0/24 dockernetwork
    docker network ls

    设置了网段为 172.18.0.0,规划主从库IP端口如下:

    主库 172.18.0.101:5432

    从库 172.18.0.102:5433


    02


    拉取 postgres:12 镜像

      docker pull postgres:12


      03


      创建数据库数据目录

        mkdir -p data/psql/master
        mkdir -p data/psql/slave
        mkdir -p data/psql/repl
        chown 999:999 data/psql/master
        chown 999:999 data/psql/slave
        chown 999:999 data/psql/repl

        master:主库数据

        slave:从库数据

        repl:临时使用复制数据


        04


        运行master容器

          docker run -d \
          --network dockernetwork --ip 172.18.0.101 -p 5432:5432 \
          --name pg12master -h pg12master \
          -e LANG="C.UTF-8" \
          -e 'TZ=Asia/Shanghai' \
          -e "POSTGRES_DB=postgres" \
          -e "POSTGRES_USER=postgres" \
          -e "POSTGRES_PASSWORD=postgres" \
          -v data/psql/master:/var/lib/postgresql/data \
          postgres:12


          05


          查看容器运行情况

            docker ps -a -f network=dockernetwork --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"


            06


            创建主从流复制专用账号

            用客户端工具连接数据库后执行以下语句,这里我使用了pgAdmin4。

              CREATE ROLE repuser WITH
              LOGIN
              REPLICATION
              CONNECTION LIMIT 5
              PASSWORD 'Q1w2E#';

              pgAdmin 也可以用 docker 来启动。

                docker pull dpage/pgadmin4
                mkdir -p data/pgadmin4
                chown 5050:5050 data/pgadmin4


                docker run -d --restart=unless-stopped \
                --network dockernetwork --ip 172.18.0.105 \
                --name pgadmin4 -h pgadmin4 \
                -e TZ=Asia/Shanghai \
                -e 'PGADMIN_DEFAULT_EMAIL=admin@pgadmin4.com' \
                -e 'PGADMIN_DEFAULT_PASSWORD=pgadmin4' \
                -p 5430:80 \
                -v data/pgadmin4:/var/lib/pgadmin \
                dpage/pgadmin4

                通过 http://ip:5430/即可访问pgadmin4,账号密码如脚本所示。具体使用也很简单,自己摸索下就懂了。


                07


                修改配置文件 data/psql/master/pg_hba.conf

                  cd /data/psql/master
                  nano pg_hba.conf

                  在文末添加如下一行,其中 repuser 即我们新建的主从专用账号,172.18.0.102/32 为从库 ip。

                    host replication repuser 172.18.0.102/32 md5


                    08


                    修改配置文件 data/psql/master/postgresql.conf

                      nano postgresql.conf

                      查找文件中以下几个参数,并调整如下:

                        archive_mode = on
                        archive_command = '/bin/date'
                        max_wal_senders = 10
                        wal_keep_segments = 16
                        synchronous_standby_names = '*'


                        09


                        重启主库使设置生效

                          #使用 pg_ctl stop 安全停止数据库
                          docker exec -it -u postgres pg12master pg_ctl stop
                          docker start pg12master



                          10


                          创建从库容器

                            docker run -d \
                            --network dockernetwork --ip 172.18.0.102 -p 5433:5432 \
                            --name pg12slave -h pg12slave \
                            -e LANG="C.UTF-8" \
                            -e 'TZ=Asia/Shanghai' \
                            -e "POSTGRES_DB=postgres" \
                            -e "POSTGRES_USER=postgres" \
                            -e "POSTGRES_PASSWORD=postgres" \
                            -v data/psql/slave:/var/lib/postgresql/data \
                            -v data/psql/repl:/var/lib/postgresql/repl \
                            postgres:12


                            这里我们把/data/psql/repl挂载到容器中,再看下容器列表:

                              docker ps -a -f network=dockernetwork --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"

                              主从库容器都已经跑起来了,当然了,这个从库还没配置。


                              11


                              进入从库容器,同步初始主库数据到 repl 目录

                                docker exec -it -u postgres pg12slave /bin/bash
                                pg_basebackup -R -D /var/lib/postgresql/repl -Fp -Xs -v -P -h 172.18.0.101 -p 5432 -U repuser


                                根据提示输入repuser的密码Q1w2E#后,会在宿主机的 /data/psql/repl 目录生成备份。

                                备份成功,退出容器。

                                  exit


                                  12


                                  重建 slave 容器

                                  通过上一步的初始备份,现在可以使用 /data/psql/repl 里的数据重建 slave容器了。首先删除slave目录,然后将repl目录改为slave,这个目录就是从库的数据目录了。

                                    docker stop pg12slave && docker rm pg12slave
                                    cd /data/psql/
                                    rm -rf slave
                                    mv repl slave
                                    cd /data/psql/slave


                                    # postgresql.auto.conf 将含有复制所需信息
                                    cat postgresql.auto.conf


                                    检查 postgresql.auto.conf 文件里是否包含如下内容:

                                      primary_conninfo = 'user=repuser password=''Q1w2E#'' host=172.18.0.101 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'


                                      正确无误后,重建容器。

                                        # 恢复重建从库容器
                                        docker run -d \
                                        --network dockernetwork --ip 172.18.0.102 -p 5433:5432 \
                                        --name pg12slave -h pg12slave \
                                        -e LANG="C.UTF-8" \
                                        -e 'TZ=Asia/Shanghai' \
                                        -e "POSTGRES_DB=postgres" \
                                        -e "POSTGRES_USER=postgres" \
                                        -e "POSTGRES_PASSWORD=postgres" \
                                        -v /data/psql/slave:/var/lib/postgresql/data \
                                        postgres:12


                                        这里不再挂载repl了,slave容器运行起来后,主从创建完成。


                                        13


                                        查看主从复制信息

                                          # 验证主从
                                          ps -aux | grep postgres
                                          # 主库有 walsender 进程如下
                                          postgres: walsender repuser
                                          # 从库有 walreceiver 进程如下
                                          postgres: walreceiver

                                          连接主库,通过sql可以查询复制信息:

                                            select * from pg_stat_replication;


                                            14


                                            总结


                                            以上是在单机环境下的演示,在实际生产环境中,只要调整相应的账号密码ip端口即可实现类似效果,其他配置信息具体根据自己需要再行调整。
                                            dotnet core 下连接PostgreSQL的库主要是Npgsql,Entity Framework Core 下可以使用包Npgsql.EntityFrameworkCore.PostgreSQL。相较于MySQL,PostgreSQL对SQL标准的支持更完整,功能更强大。网上对这两个数据库的比较很多,这里就不多赘述了。


                                            欢迎关注公众号 "dotnet 新征程"

                                            文章转载自dotnet 新征程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                            评论