三只linux发行版数据库,MariaDB10.3 系统版本表 有效防止数据丢失

系统版本表是SQL:2011标准中首次引入的功能。系统版本表存储所有更改的历史数据,而不仅仅是当前时刻有效的数据。举个例子,同一行数据一秒内被更改了10次,那么就会保存10份不同时间的版本数据。就像《源代码》电影里的平行世界理论一样,你可以退回任意时间里。从而有效保障你的数据是安全的,DBA手抖或程序BUG引起的数据丢失,在MariaDB10.3里已成为过去。

一、创建系统版本表

例子:

CREATE TABLE `t1` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(100) DEFAULT NULL,

`ts` timestamp(6) GENERATED ALWAYS AS ROW START,

`te` timestamp(6) GENERATED ALWAYS AS ROW END,

PRIMARY KEY (`id`,`te`),

PERIOD FOR SYSTEM_TIME (`ts`, `te`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 WITH SYSTEM VERSIONING;

注意看红色字体,这就是新增加的语法,字段ts和te是数据变化的起止时间和结束时间。

另外用ALTER TABLE更改表结构,语法如下:

ALTER TABLE t1 ADD COLUMN ts TIMESTAMP(6) GENERATED ALWAYS AS ROW START,

ADD COLUMN te TIMESTAMP(6) GENERATED ALWAYS AS ROW END,

ADD PERIOD FOR SYSTEM_TIME(ts, te),

ADD SYSTEM VERSIONING;

二、查询历史数据

这里我们做一个实验,首先要插入1条数据,如下图所示:

b3b50e7ef02c0452737a354b97624447.png

接着把姓名为“张三”,改成“李四”(误更改数据)

b6c06a9f4c0fb3ff2e52bdafce5f7d55.png

现在数据已经成功变更,那么我想查看历史数据怎么办呢?非常简单,一条命令搞定。

语法一:查询一小时内的历史数据。

SELECT * FROM t FOR SYSTEM_TIME BETWEEN (NOW() - INTERVAL 1 HOUR) AND NOW();

HOUR:小时

MINUTE:分钟

DAY:天

MONTH:月

YEAR:年

语法二:查询一段时间内的历史数据

SELECT * FROM t1 FOR SYSTEM_TIME FROM '2018-05-15 00:00:00' TO '2018-05-15 14:00:00';

c4e4426588e30eed36968da3f37efb06.png

语法三:查询所有历史数据

SELECT * FROM t1 FOR SYSTEM_TIME ALL;

6926203b151303860ab8565b84197725.png

三、恢复历史数据

现在我们已经找到了历史数据“张三”,只需把它导出来做恢复即可。

SELECT id,name FROM t1 FOR SYSTEM_TIME ALL where id = 1 AND name =

'张三' into outfile '/tmp/t1.sql' \

FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"';

FIELDS TERMINATED BY ',' --- 字段的分隔符

OPTIONALLY ENCLOSED BY '"' --- 字符串带双引号

导入恢复

load data infile '/tmp/t1.sql' replace into table t1 \

FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' \

(id,name);

485397652ac0c18dcddd0571c3ff6d2b.png

非常简单的恢复完数据,此方法比之前用mysqlbinlog或自研脚本等工具做闪回效率高得多。

四、单独存储历史数据

当历史数据与当前数据一起存储时,势必会增加表的大小,且当前的数据查询:表扫描和索引搜索,将会花费更多的时间,因为需要跳过历史数据。那么我们可以将通过表分区将其分开、单独存储,以减少版本控制的开销。

接上面的例子,执行下面的语句:

alter table t1

PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH (

PARTITION p0 HISTORY,

PARTITION p1 HISTORY,

PARTITION p2 HISTORY,

PARTITION p3 HISTORY,

PARTITION p4 HISTORY,

PARTITION p5 HISTORY,

PARTITION p6 HISTORY,

PARTITION pcur CURRENT

);

意思为:按照月份分割历史数据,今天至一个月后(2018年6月15日)的历史数据放入p0分区,次月的历史数据放入p1分区,依次类推至(2018年12月15日)存p6分区。当前数据存储在pcur分区里。

8653c9ab2115f7f713cbf84e9babda44.png

921703f8d1f40c5e8f65b1805659d65e.png

可以通过数据字典表,来查看每个分区表的数据轮询时间状态信息。

SELECT PARTITION_DESCRIPTION,TABLE_ROWS FROM

`information_schema`.`PARTITIONS` WHERE table_schema='hcy' AND

table_name='t1';

a6e1bf4b45e2d0aea7248576c1f3b387.png

五、删除旧的历史数据

系统版本表存储了所有的历史数据,随着时间的推移,历史版本数据会变得越来越大,那么我们就可以将其最老的历史数据删除。

例:将p0分区删除

ALTER TABLE t1 DROP PARTITION p0;

b2152efa8e9687e5fe5448edc077c6fd.png

六、正确使用姿势

通过上述介绍,我们了解了系统版本表的原理。在高并发写入场景下,势必会带来性能上的损失,所以要用正确的姿势开启该功能。

例:主库是MySQL 5.6或者MariaDB 10.0/1/2版本,搭建一个新从库MariaDB 10.3,在该从库上转换为系统版本控制表。这样主库上误删或误篡改数据,可以在从库上通过版本控制找回。

9c2174b1d6837bd386570ec0ad6ee2b5.png

注:主库是低版本,从库是高版本,是可以向前兼容binlog格式的。

七、注意事项

1、参数system_versioning_alter_history要设置为KEEP(在my.cnf配置文件里写死),否则默认不能执行DDL修改表结构操作。

set global system_versioning_alter_history = 'KEEP';

注:增加字段时,要加上after关键字,否则会在te字段后面,造成同步失败。例:

alter table t1 add column address varchar(500) after name;

2、mysqldump工具不会导出历史数据,所以在做备份时,可以通过Percona XtraBackup热备份工具来备份物理文件。

3、搭建从库时,如果你用mysqldump工具,要先导出表结构文件,再导出数据。

1)只导出表结构:

# mysqldump -S /tmp/mysql3306.sock -uroot -p123456 --single-transaction --compact -c -d -q -B test > ./test_schema.sql

导入完表结构后,批量执行DDL转换系统版本表,脚本如下(附件里点击下载):

# cat convert.php

$conn=mysqli_connect("10.10.100.11","admin","123456","test","3306") or die("error connecting");

mysqli_query($conn,"SET NAMES utf8");

$table = "show tables";

$result1 = mysqli_query($conn,$table);

while($row = mysqli_fetch_array($result1)){

$table_name=$row[0];

echo "$table_name 表正在进行转换系统版本表。。。".PHP_EOL;

$convert_table="

ALTER TABLE {$table_name} ADD COLUMN ts TIMESTAMP(6) GENERATED ALWAYS AS ROW START,

ADD COLUMN te TIMESTAMP(6) GENERATED ALWAYS AS ROW END,

ADD PERIOD FOR SYSTEM_TIME(ts, te),

ADD SYSTEM VERSIONING";

$result2=mysqli_query($conn,$convert_table);

if($result2){

echo '更改表结构成功.'.PHP_EOL;

echo ''.PHP_EOL;

}

else{

echo '更改表结构失败.'.PHP_EOL;

echo ''.PHP_EOL;

}

}

mysqli_close($conn);

?>

注:先安装php-mysql驱动

#yum install php php-mysql -y

#php convert.php

41c7e2200e1176927db659e2960df4b5.png

2)只导出数据:

# mysqldump -S /tmp/mysql3306.sock -uroot -p123456 --single-transaction

--master-data=2 --compact -c -q -t -B test > test_data.sql

参考文档:

https://mariadb.com/kb/en/library/system-versioned-tables/0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用于MariaDB的Navicat为MariaDB数据库管理和开发提供了本机环境。连接到本地/远程MariaDB服务器,并与Amazon RDS兼容。适用于MariaDB的Navicat支持大多数附加功能,例如新的存储引擎,微秒,虚拟列等。 直观且经过精心设计的GUI简化了数据库管理和开发。 数据传输,数据同步和结构同步可帮助您更轻松快捷地迁移数据,从而减少开销。提供详细的分步指南,以跨数据库传输数据。使用数据和结构同步来比较和同步数据库。在几秒钟内设置和部署比较,并获取详细的脚本以指定要执行的更改。 设置数据源连接后,可以使用“导入向导”将数据从多种格式或从ODBC传输到数据库中。将格,视图或查询结果中的数据导出为Excel,Access,CSV等格式。使用类似于电子格的网格视图以及一系列数据编辑工具来添加,修改和删除记录,以方便您进行编辑。Navicat为您提供有效管理数据并确保流程平稳所需的工具。 Visual SQL Builder将帮助您创建,编辑和运行SQL语句,而不必担心语法和命令的正确用法。通过获取关键字建议并从编码中去除重复内容,使用“代码完成”和可自定义的代码段快速进行编码。 使用我们专业的对象设计器创建,修改和管理所有数据库对象。使用复杂的数据库设计和建模工具将数据库转换为图形示形式,以便您可以轻松地建模,创建和理解复杂的数据库。 我们的图功能使您可以创建大型数据集的可视示形式,并帮助您从数据中获得更深刻的见解。探索并发掘数据之间的模式,趋势和关系,并创建有效的视觉输出,以将您的发现显示在仪板上以进行共享。 我们强大的本地备份/还原解决方案可指导您完成备份过程,并减少发生错误的可能性。为可重复部署的过程设置自动化,例如在特定时间或日期执行数据库备份和脚本执行。无论您身在何处,都可以随时完成工作。 将您的连接设置,模型,查询和虚拟组同步到我们的Navicat Cloud服务,以便您可以实时访问它们,并随时随地与您的同事共享。借助Navicat Cloud,您可以利用一天中的每一分钟来最大限度地提高生产力。 通过SSH隧道和SSL建立安全连接,可确保每个连接都是安全,稳定和可靠的。支持数据库服务器的不同身份验证方法,例如PAM身份验证。Navicat提供了更多的身份验证机制和高性能环境,因此您不必担心通过不安全的网络进行连接。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值