查看原文
其他

Oracle / MySQL 数据库高可用方案三大难点问题

点击蓝字关注👉 twt企业IT社区 2022-07-03

以下内容由社区专家岳彩波根据社区交流活动总结


1、超大数据库的在线迁移问题和归档问题

随着信息的大爆炸,互联网各种业务的发展,超大、超级大的数据库都已经出现,先说一下迁移问题,oracle的迁移有很多种方案,迁移T级数据目前有XTTS等官方推荐的一些方案,PB级数据那就需要专业团队来根据实际情况来做一个完善的迁移方案。目前我也没接触过这种数据库的迁移,希望能和大家共同学习。再来说一下mysql超大的数据库,T级以上的单数据库在生产环境中不是很多,所以迁移的难点可能就是在于分库分表,数据库一致等问题,在这里分享几个可用方案:

方案1

In this case, normally, the best solution is a mysqldump using the --tab option like this:

mysqldump --tab=/path/to/serverlocaldir --single-transaction <database> table_a

tab option produce 2 file, one file -table_a.sql- that contains only the table create statement and the oher file -table_a.txt- contains tab-separated data.

Now you can create your new table

create table table_b like table_a;

Then you simply load data in your new table via LOAD DATA without care for the table's name.

LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt' 

  INTO TABLE table_b FIELDS TERMINATED BY ' ' ...

LOAD DATA is usually 20 times faster than using INSERT statements.

LOAD DATA速度比INSERT语句要快,这里其实倒入也可以使用mysqlimport命令

方案2

I recently moved a 30GB database with the following stragegy:

Old Server

Stop mysql server

Copy contents of datadir to another location on disk (~/mysqldata/*)

Start mysql server again (downtime was 10-15 minutes)

compress the data (tar -czvf mysqldata.tar.gz ~/mysqldata)

copy the compressed file to new server

New Server

install mysql (don't start)

unzip compressed file (tar -xzvf mysqldata.tar.gz)

move contents of mysqldata to the datadir

Make sure your innodb_log_file_size is same on new server, or if it's not, don't copy the old log files (mysql will generate these)

Start mysql

这种方法就是直接复制数据库的文件结构,要求必须相同的mysql版本,和相同的配置才可以用这种方法

方案3

If you are considering migrating to another DB Server with the exact same version of MySQL, you may want torsync the datadir from the old server to the new server.

This will work regardless of InnoDB file layout or even the presence of MyISAM tables.

install the same version of mysql on ServerB that ServerA has

On ServerA, run RESET MASTER; to erase all binary logs before the rsycn process. If binary logging is not enabled, you can skip this step.

On ServerA, run SET GLOBAL innodb_max_dirty_pages_pct = 0; from mysql and about 10 minutes (This purges dirty pages from the InnoDB Buffer Pool. It also helps perform a mysql shutdown faster) If your database is all MyISAM, you can skip this step.

rsync /var/lib/mysql of ServerA to /var/lib/mysql on ServerB

Repeat Step 3 until an rsync takes less than 1 minute

service mysql stop on ServerA

Perform one more rsync

scp ServerA:/etc/my.cnf to ServerB:/etc/.

service mysql start on ServerB

service mysql start on ServerA (optional)

Essentially, here is what such a script would like this

其实这个跟方案2是一样的。只是操作方法不同而已,当然要求也是一样的。


2、超大数据备份问题

超大数据备份其实和迁移归档都能放在一起说,这里单独拿出来总结一下就是因为备份和迁移毕竟是两个概念,大家关注的也比较多。

数据备份是容灾的基础,有了备份不等于万事大吉。因为备份的数据可以还会有其他因素造成的数据损坏,如地震、火灾等,对于这些企业应该在数据容灾方面提升能力,来进一步应对数据抵抗潜在不安全因素的能力。当然,数据备份还是最基础的形式,没有数据备份,任何容灾都没有现实意义。目前来看,主要的数据备份方式如下:

定期磁带备份:包括远程磁带库、光盘库备份和远程关键数据+磁带备份。

数据库备份:就是在与主数据库所在生产机相分离的备份机上建立主数据库的一个拷贝。

网络数据:这种方式是对生产系统的数据库数据和所需跟踪的重要目标文件的更新进行监控与跟踪,并将更新日志实时通过网络传送到备份系统,备份系统则根据日志对磁盘进行更新。

远程镜像:通过高速光纤通道线路和磁盘控制技术将镜像磁盘延伸到远离生产机的地方,镜像磁盘数据与主磁盘数据完全一致,更新方式为同步或异步。

这些措施能够在系统发生故障后进行系统恢复。但是这些措施一般只能处理计算机单点故障,对区域性、毁灭性灾难则束手无策,也不具备灾难恢复能力。所以我们就需要建立异地容灾中心,做数据的远程备份,在灾难发生之后要确保原有的数据不会丢失或者遭到破坏。建立的异地容灾中心可以简单地把它理解成一个远程的数据备份中心。数据容灾的恢复时间比较长,但是相比其他容灾级别来讲它的费用比较低,而且构建实施也相对简单。主要的实施方法如下:

实时复制:当主中心的数据库内容被修改时,备份中心的数据库内容实时地被修改,此种复制方式对网络可靠性要求高。

定时复制:当主中心的数据库内容被修改时,备份中心的数据库内容会按照时间间隔,周期性地按照主中心的更新情况进行刷新,时间间隔可长(几天或几个月)可短(几分钟或几秒钟)。

存储转发复制:当主中心的数据库内容被修改时,主中心的数据库服务器会先将修改操作Log存储于本地,待时机成熟再转发给备份中心。


3、oracle和mysql数据库在高可用中数据一致性问题

oracle的数据一致性这里就不用说了,已经做的很完善,很少出现问题,出现问题也有完整的方案来解决,主要说一下mysql数据的一致性。就说一下最简单的mysql主从复制方案吧,供大家参考一下。

现在常用的MySQL高可用方案,十有八九是基于MySQL的主从复制(replication)来设计的,包括常规的一主一从、双主模式,或者半同步复制(semi-sync replication)。

我们常常把MySQL replication说成是MySQL同步(sync),但事实上这个过程是异步(async)的。大概过程是这样的:

  • 在master上提交事务后,并且写入binlog,返回事务成功标记;

  • 将binlog发送到slave,转储成relay log;

  • 在slave上再将relay log读取出来应用。

  • 步骤1和步骤3之间是异步进行的,无需等待确认各自的状态,所以说MySQL replication是异步的。

  • MySQL semi-sync replication在之前的基础上做了加强完善,整个流程变成了下面这样:

  • 首先,master和至少一个slave都要启用semi-sync replication模式;

  • 某个slave连接到master时,会主动告知当前自己是否处于semi-sync模式;

  • 在master上提交事务后,写入binlog后,还需要通知至少一个slave收到该事务,等待写入relay log并成功刷新到磁盘后,向master发送“slave节点已完成该事务”确认通知;

  • master收到上述通知后,才可以真正完成该事务提交,返回事务成功标记;

在上述步骤中,当slave向master发送通知时间超过rpl_semi_sync_master_timeout设定值时,主从关系会从semi-sync模式自动调整成为传统的异步复制模式。

半同步复制看起来很美好有木有,但如果网络质量不高,是不是出现抖动,触发上述第5条的情况,会从半同步复制降级为普通复制;此外,采用半同步复制,会导致master上的tps性能下降非常严重,最严重的情况下可能会损失50%以上。

这样来看,除非需要非常严格保证数据一致性等迫不得已的场景,就不太建议使用半同步复制了。当然了,事实上我们也可以通过加强程序端的逻辑控制,来避免主从数据不一致时发生逻辑错误,比如说如果在从上读取到的数据和主不一致的话,那么就触发主从间的一次数据修复工作。或者,我们也可以用 pt-table-checksum & pt-table-sync 两个工具来校验并修复数据,只要运行频率适当,是可行的。

真想要提高多节点间的数据一致性,可以考虑采用PXC方案。现在已知用PXC规模较大的有qunar、sohu,如果团队里初期没有人能比较专注PXC的话,还是要谨慎些,毕竟和传统的主从复制差异很大,出现问题时需要花费更多精力去排查解决。

如何保证主从复制数据一致性:

上面说完了异步复制、半同步复制、PXC,我们回到主题:在常规的主从复制场景里,如何能保证主从数据的一致性,不要出现数据丢失等问题呢?

在MySQL中,一次事务提交后,需要写undo、写redo、写binlog,写数据文件等等。在这个过程中,可能在某个步骤发生crash,就有可能导致主从数据的不一致。为了避免这种情况,我们需要调整主从上面相关选项配置,确保即便发生crash了,也不能发生主从复制的数据丢失。

  1. 在master上修改配置
    innodb_flush_log_at_trx_commit = 1
    sync_binlog = 1
    上述两个选项的作用是:保证每次事务提交后,都能实时刷新到磁盘中,尤其是确保每次事务对应的binlog都能及时刷新到磁盘中,只要有了binlog,InnoDB就有办法做数据恢复,不至于导致主从复制的数据丢失。

  2. 在slave上修改配置
    master_info_repository = "TABLE"
    relay_log_info_repository = "TABLE"
    relay_log_recovery = 1

上述前两个选项的作用是:确保在slave上和复制相关的元数据表也采用InnoDB引擎,受到InnoDB事务安全的保护,而后一个选项的作用是开启relay log自动修复机制,发生crash时,会自动判断哪些relay log需要重新从master上抓取回来再次应用,以此避免部分数据丢失的可能性。

通过上面几个选项的调整,就可以确保主从复制数据不会发生丢失了。但是,这并不能保证主从数据的绝对一致性,因为,有可能设置了ignoredo ewrite等replication规则,或者某些SQL本身存在不确定因素,或者人为在slave上修改数据,最终导致主从数据不一致。这种情况下,可以采用pt-table-checksum 和 pt-table-sync 工具来进行数据的校验和修复。


点击阅读原文关注社区  高可用技术主题 ,将会不断更新优质资料、文章,您也可以前往提出疑难问题,与同行切磋交流。


下载 twt 社区客户端 APP

与更多同行在一起

高手随时解答你的疑难问题

轻松订阅各领域技术主题

浏览下载最新文章资料


长按识别二维码即可下载

或到应用商店搜索“twt”


长按二维码关注公众号

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存