TL;DR
前文介绍了如何在 Rocky Linux 9 上安装 YashanDB 个人版,初体验过后,上点难度。
本文将介绍如何在本地环境,定制 Dockerfile 并自行构建 YashanDB 个人版的 Docker 镜像。
以及,基于该 Docker 镜像,启动两个容器,配置 YashanDB 的主备高可用。
本文篇幅略长,直接上干货,如有疑问,欢迎讨论。
定制 Dockerfile 构建 YashanDB 个人版镜像
这里就不赘述 Docker 的各种优势了,只是需要说明的是,本文使用的环境为 Rocky 9,docker 已经被 podman 所取代。
Dockerfile 的大体思路是:
- 以 CentOS 7 为基础镜像,安装几个常用软件包
- 创建
yashan
用户,后面的操作将在该用户下进行 - 下载 YashanDB 个人版的安装包,并解压
- 使用 YashanDB 个人版安装包里的脚本安装崖山数据库
具体 Dockerfile 内容如下:
FROM centos:7 LABEL maintainer="Shawn Yan" # Install requirements. RUN yum install -y wget iproute epel-release \ && yum install -y rlwrap \ && yum clean all # Env. ENV YASDB_PKG="yashandb-personal-23.1.1.100-linux-x86_64.tar.gz" YASDB_INSTALL=/tmp/yashan # Create User RUN useradd -u 2023 yashan \ && echo "if command -v rlwrap >/dev/null 2>&1; then alias yasql='rlwrap yasql'; fi" >> /home/yashan/.bashrc # Download YashanDB pkg. RUN wget https://linked.yashandb.com/resource/$YASDB_PKG -P /tmp \ && mkdir $YASDB_INSTALL \ && tar zxf /tmp/$YASDB_PKG -C $YASDB_INSTALL \ && rm -f /tmp/$YASDB_PKG # Init. RUN chown -R yashan:yashan $YASDB_INSTALL \ && su -l yashan -c "$YASDB_INSTALL/scripts/install.sh" 2>&1 < /dev/null # Mount EXPOSE 1688 VOLUME ["/tmp"] CMD ["/usr/sbin/init"]
使用 podman 构建镜像,调试 dockerfile 耗费了半天时间,skill 有些生疏了。
podman build -f Dockerfile -t shawnyan.cn/myyashan . podman images
到此,YashanDB 个人版镜像已经制作完成。
由于某些原因,Docker Hub 的上载、下行网速实在堪忧,建议感兴趣、有需求的同学在本地自行构建镜像,会更快、高效。
启动 YashanDB 容器,并初始化
为了搭建 YashanDB 主备高可用,两个容器需要在一个网段,保证能够相互通信。这里先创建一个桥接网络,并在容器初始化时指定 IP 地址。
podman network create -d bridge --subnet=10.188.0.0/16 mynw podman run --name yas1 --hostname yashan1 \ --network mynw --ip 10.188.0.11 \ -v /data/yas1:/tmp \ -d shawnyan.cn/myyashan podman run --name yas2 --hostname yashan2 \ --network mynw --ip 10.188.0.12 \ -v /data/yas2:/tmp \ -d shawnyan.cn/myyashan podman ps
输出如下:
[root@rocky9 ~]# podman run --name yas1 --hostname yashan1 \ --network mynw --ip 10.188.0.11 \ -v /data/yas1:/tmp \ -d shawnyan.cn/myyashan ad4d90c05055ea4cbf23b0467db19665b7a4e94ed5ea3bf185cc446c2deb55b3 [root@rocky9 ~]# podman run --name yas2 --hostname yashan2 \ --network mynw --ip 10.188.0.12 \ -v /data/yas2:/tmp \ -d shawnyan.cn/myyashan 232ec61af1f444e26ef89234f247a5c6c988d92e08498456b9f50fda994e3df9 [root@rocky9 ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ad4d90c05055 shawnyan.cn/myyashan:latest /usr/sbin/init 20 seconds ago Up 19 seconds yas1 232ec61af1f4 shawnyan.cn/myyashan:latest /usr/sbin/init 6 seconds ago Up 5 seconds yas2 [root@rocky9 ~]#
上图也可以看到启动后的两个容器。
分别进入 yas1 和 yas2 两个容器。
podman exec -it yas1 bash podman exec -it yas2 bash
切换到 yashan 用户,并初始化数据库。
su - yashan ~/yashandb/yasdb_home/scripts/initDB.sh
稍等片刻,数据库启动,我们来连接数据库,查看一下数据库启动状态和数据库名称。
yasql sys/yasdb_123 SELECT STATUS FROM V$INSTANCE; SELECT database_name FROM v$database;
- output, yas1:
[root@yashan1 /]# su - yashan
Last login: Thu Nov 23 10:04:38 UTC 2023
[yashan@yashan1 ~]$ ~/yashandb/yasdb_home/scripts/initDB.sh
process started!
Database open succeed !
[yashan@yashan1 ~]$ yasql sys/yasdb_123
YashanDB SQL Personal Edition Release 23.1.1.100 x86_64
Connected to:
YashanDB Server Personal Edition Release 23.1.1.100 x86_64 - X86 64bit Linux
SELECT STATUS FROM V$INSTANCE;
STATUS
-------------
OPEN
1 row fetched.
SQL> SELECT database_name FROM v$database;
DATABASE_NAME
----------------------------------------------------------------
yasdb
1 row fetched.
SQL>
- output, yas2:
[root@yashan2 /]# su - yashan
Last login: Thu Nov 23 10:04:38 UTC 2023
[yashan@yashan2 ~]$ ~/yashandb/yasdb_home/scripts/initDB.sh
process started!
Database open succeed !
[yashan@yashan2 ~]$ yasql sys/yasdb_123
YashanDB SQL Personal Edition Release 23.1.1.100 x86_64
Connected to:
YashanDB Server Personal Edition Release 23.1.1.100 x86_64 - X86 64bit Linux
SELECT STATUS FROM V$INSTANCE;
STATUS
-------------
OPEN
1 row fetched.
SQL> SELECT database_name FROM v$database;
DATABASE_NAME
----------------------------------------------------------------
yasdb
1 row fetched.
SQL>
到此,我们已经准备了两个数据库,接下来进行主备配置。
主备配置
YashanDB支持主备模式(一主多备)和级联备模式(不限层级)的高可用部署架构。
主备复制中,通过主机发送redo日志,备机接收日志并回放,以实现备机和主机的在线同步。YashanDB采用环形Log Cache缓存redo日志,同步模式下日志发送和备机回放优先从缓存读取数据,提高速度。
依据官网说明,我们先进行主备参数配置,下面的步骤分别在 yas1 和 yas2 上进行。
-- LISTEN_ADDR:本机数据库的IP与监听端口,该参数在安装时已配置。
ALTER SYSTEM SET LISTEN_ADDR=0.0.0.0:1688 scope=spfile;
-- REPLICATION_ADDR:本机数据库的IP与同步复制端口,可不配置,则与LISTEN_ADDR共享一个端口。
ALTER SYSTEM SET REPLICATION_ADDR=0.0.0.0:1689 scope=spfile;
-- 开启归档
ALTER DATABASE ARCHIVELOG;
-- 重啓到 mount 模式
shutdown;
nohup yasdb mount &
-- ARCHIVE_DEST_1:对端数据库的IP与同步复制端口,必须配置。
-- yas2
ALTER SYSTEM SET ARCHIVE_DEST_1='SERVICE=10.188.0.11:1689' scope=both;
-- yas1
ALTER SYSTEM SET ARCHIVE_DEST_1='SERVICE=10.188.0.12:1689' scope=both;
下面的步骤在备机上操作,将备机切换到 Standby 状态。
-- 備機
ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
SELECT DATABASE_NAME,LOG_MODE,OPEN_MODE,DATABASE_ROLE,CURRENT_SCN,STATUS,RESTORE_TIME,HOST_NAME FROM V$DATABASE;
ALTER DATABASE OPEN;
SELECT CONNECTION,STATUS,PEER_ADDR,TRANSPORT_LAG,APPLY_LAG FROM V$REPLICATION_STATUS;
- output, yas2
SQL> SELECT CONNECTION,STATUS,PEER_ADDR,TRANSPORT_LAG,APPLY_LAG FROM V$REPLICATION_STATUS;
CONNECTION STATUS PEER_ADDR TRANSPORT_LAG APPLY_LAG
----------------- ----------------- ---------------------------------------------------------------- ------------- ------------
CONNECTED NEED REPAIR 0.0.0.0:1689 568363 568363
1 row fetched.
主备相关参数已设定完成,这里看到备机的连接状态为 CONNECTED
,说明已连接成功,但是状态为 NEED REPAIR
,需要修復複製。
关于修复 NEED REPAIR
的更多内容,可阅读官方文档:备机NEED REPAIR
接下来演示如何通过全量数据恢复来修复同步。
全量备份恢复
- 在 yas1 主节点,创建全量备份。
-- 执行全量备份,生成全量备份集 bak_xxx
BACKUP DATABASE;
- output, yas1
SQL> BACKUP DATABASE;
Succeed.
[yashan@yashan1 backup]$ pwd
/home/yashan/yashandb/yasdb_data/backup
[yashan@yashan1 backup]$ ls
bak_2023112315425603
- 在 yas2 备节点,恢复全量备份。
-- 停机,启动为 nomount 状态
shutdown;
nohup yasdb nomount &
-- 删除现存库,执行 RESTORE 命令恢复备份
yasql sys/yasdb_123
drop database;
RESTORE DATABASE FROM '/tmp/bak_2023112315425603';
-- 启动为 STANDBY 状态,并执行 RECOVER 命令
ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
RECOVER DATABASE;
-- 打开数据库
ALTER DATABASE OPEN;
- output, yas2:
SQL> ! hostname
yashan2
SQL> SELECT CONNECTION,STATUS,PEER_ADDR,TRANSPORT_LAG,APPLY_LAG FROM V$REPLICATION_STATUS;
CONNECTION STATUS PEER_ADDR TRANSPORT_LAG APPLY_LAG
----------------- ----------------- ---------------------------------------------------------------- ------------- ------------
CONNECTED NORMAL 0.0.0.0:1689 0 0
1 row fetched.
SQL> SELECT DATABASE_NAME,LOG_MODE,OPEN_MODE,DATABASE_ROLE,CURRENT_SCN,STATUS,RESTORE_TIME,HOST_NAME FROM V$DATABASE;
DATABASE_NAME LOG_MODE OPEN_MODE DATABASE_ROLE CURRENT_SCN STATUS RESTORE_TIME HOST_NAME
---------------------------------------------------------------- ----------------- ----------------- ----------------- --------------------- --------------------------------- -------------------------------- ----------------------------------------------------------------
yasdb ARCHIVELOG READ_ONLY STANDBY 503469581563842560 NORMAL yashan2
1 row fetched.
到此,yas2 备节点已恢复完成,并与 yas1 主节点正常建立连接。
验证测试
驗證:在 yas1 主庫裏創建表 t1
,在 yas2 從庫裏查看表是否創建成功。
create user sbtest;
create table sbtest.t1 (id int);
以及,插入數據到表 t1
,在從庫中確認數據已經同步。
insert into sbtest.t1 values (1);
commit;
总结
本文演示了如何在本地环境构建 YashanDB 个人版镜像,基于此可以快速、反复做各种实现,是学习、测试利器。
以及,在此基础之上,演示搭建 YashanDB 的主备高可用架构。
由于个人版的限制,分布式和共享集群没有办法尝试搭建了,接下来会分享其他方面的内容。