searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

mysql-pg序列同步方法

2023-07-28 03:32:48
6
0

序列是一种数据库对象,它可以生成一系列按一定规则递增(或递减)的数值,常用于生成表的主键值。一个序列对象包含名称、起始值、增量值等属性。Oracle、PostgreSQL等数据库中都有序列。MySQL中没有序列,但可以使用AUTO_INCREMENT关键字来生成自增主键,达到类似序列的效果。

随着数据容灾业务和数据库迁移业务的增加,需要确保两端数据库序列一致,使得应用层切换数据库后产生的序列值不会冲突。例如数据表的主键使用了自增序列,如果序列不一致,应用侧切换数据库后插入数据时,可能会生成已存在的主键值,导致入库失败和应用报错。

下面以mysql到postgresql的同步为例,介绍一种较为通用的序列同步方法,总体分为序列匹配、序列属性值同步、序列核对三个步骤。mysql源表的ddl如下:

CREATE TABLE `oper_log` (
  `log_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `oper_result` tinyint(4) DEFAULT NULL,
  `created_time` datetime NOT NULL,
  PRIMARY KEY (`log_id`)
);

对应的postgreSQL目标表ddl如下:

CREATE TABLE "oper_log" (
  "log_id" BIGINT NOT NULL UNIQUE DEFAULT nextval('"oper_log_id_seq"'),
  "oper_result" SMALLINT,
  "created_time" TIMESTAMP NOT NULL,
  PRIMARY KEY ("log_id")
);

序列匹配

通过识别源表ddl中的auto_increment关键字,可知log_id字段使用了自增序列。查找目标表中log_id字段使用的序列,语句如下:

SELECT column_default FROM information_schema.COLUMNS WHERE "table_name"='oper_log' AND "column_name"='log_id' AND column_default ILIKE 'nextval(%';

根据语句返回结果可得知序列名为oper_log_id_seq。执行如下语句,如果oper_log_id_seq不存在则会创建。由于mysql自增序列的默认起始值和增量值都是1,所以我们创建序列时也设置起始值和增量值为1。

CREATE SEQUENCE IF NOT EXISTS "oper_log_id_seq" START WITH 1 INCREMENT BY 1;

序列属性值同步

属性值包括初始值、增量值、最小值、最大值、当前值等。其中比较常用的是当前值,它是序列产生的最新数值。由于mysql和postgresql是异构数据库,需要对序列属性做一些转换。如果mysql的一些序列属性在postgresql中不被支持,则需要舍弃掉这部分属性。以同步序列的当前值为例,首先读取源表序列的当前值:

select auto_increment from information_schema.`TABLES` where TABLE_NAME = 'oper_log';

假设读取出的值是100,那么更新oper_log_id_seq的当前值为100:

SELECT setval('oper_log_id_seq', 100, false);

序列核对

读取mysql序列当前值的方法与上一步相同。读取pg表的oper_log_id_seq的当前值,并对比两者的当前值是否一致。

select last_value from 'oper_log_id_seq';
0条评论
0 / 1000
4****m
2文章数
0粉丝数
4****m
2 文章 | 0 粉丝
4****m
2文章数
0粉丝数
4****m
2 文章 | 0 粉丝
原创

mysql-pg序列同步方法

2023-07-28 03:32:48
6
0

序列是一种数据库对象,它可以生成一系列按一定规则递增(或递减)的数值,常用于生成表的主键值。一个序列对象包含名称、起始值、增量值等属性。Oracle、PostgreSQL等数据库中都有序列。MySQL中没有序列,但可以使用AUTO_INCREMENT关键字来生成自增主键,达到类似序列的效果。

随着数据容灾业务和数据库迁移业务的增加,需要确保两端数据库序列一致,使得应用层切换数据库后产生的序列值不会冲突。例如数据表的主键使用了自增序列,如果序列不一致,应用侧切换数据库后插入数据时,可能会生成已存在的主键值,导致入库失败和应用报错。

下面以mysql到postgresql的同步为例,介绍一种较为通用的序列同步方法,总体分为序列匹配、序列属性值同步、序列核对三个步骤。mysql源表的ddl如下:

CREATE TABLE `oper_log` (
  `log_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `oper_result` tinyint(4) DEFAULT NULL,
  `created_time` datetime NOT NULL,
  PRIMARY KEY (`log_id`)
);

对应的postgreSQL目标表ddl如下:

CREATE TABLE "oper_log" (
  "log_id" BIGINT NOT NULL UNIQUE DEFAULT nextval('"oper_log_id_seq"'),
  "oper_result" SMALLINT,
  "created_time" TIMESTAMP NOT NULL,
  PRIMARY KEY ("log_id")
);

序列匹配

通过识别源表ddl中的auto_increment关键字,可知log_id字段使用了自增序列。查找目标表中log_id字段使用的序列,语句如下:

SELECT column_default FROM information_schema.COLUMNS WHERE "table_name"='oper_log' AND "column_name"='log_id' AND column_default ILIKE 'nextval(%';

根据语句返回结果可得知序列名为oper_log_id_seq。执行如下语句,如果oper_log_id_seq不存在则会创建。由于mysql自增序列的默认起始值和增量值都是1,所以我们创建序列时也设置起始值和增量值为1。

CREATE SEQUENCE IF NOT EXISTS "oper_log_id_seq" START WITH 1 INCREMENT BY 1;

序列属性值同步

属性值包括初始值、增量值、最小值、最大值、当前值等。其中比较常用的是当前值,它是序列产生的最新数值。由于mysql和postgresql是异构数据库,需要对序列属性做一些转换。如果mysql的一些序列属性在postgresql中不被支持,则需要舍弃掉这部分属性。以同步序列的当前值为例,首先读取源表序列的当前值:

select auto_increment from information_schema.`TABLES` where TABLE_NAME = 'oper_log';

假设读取出的值是100,那么更新oper_log_id_seq的当前值为100:

SELECT setval('oper_log_id_seq', 100, false);

序列核对

读取mysql序列当前值的方法与上一步相同。读取pg表的oper_log_id_seq的当前值,并对比两者的当前值是否一致。

select last_value from 'oper_log_id_seq';
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0