search 2013 adfgs

之前说起 将参加 2010 数据库技术大会,今天将这次参会使用的 PPT 贴出来,或许会对大家有点用。 先大概介绍下大会的几本情况吧,满满2天的大会,共安排了 29 场演讲,内容涵盖了 Oracle,MySQL,DB2,SQL Server ,Sybase,达梦(国产数据库) 等多种数据库,演讲数量之多,主题内容之丰富,实数罕见,哈哈。演讲嘉宾的阵容也非常庞大,国内14个 ACE / ACE Director,其中9位到场演讲。 各个主题内容的 PPT 可以到 此处下载 ,这里我大概介绍下“高可用可扩展数据库架构” 这个话题吧: 在主题中,我从数据库的 高可用 和 可扩展 两个方面来进行了分享探讨: 高可用 软/硬件高可用(热/冷备) 数据高可用(共享,同/异步复制) 单独的硬件高可用除了冗余之外本身没有太多可以讲的,所以一笔带过。 基于共享设备的数据高可用只是大概的介绍了可能的方案,由于各方案的实施都比较昂贵,更适合于Oracle,DB2等,所以也没有深入探讨。 所以,这部分重点介绍了一下利用 MySQL 的 Replication 技术和应用程序的共同配合来实现 Share Nothing 方式的高可用。 可扩展 向上扩展(Scale Up) 硬件扩容(增加CPU数量,增加内存容量,增加磁盘数量…) 硬件升级(更换更高端的主机,更换更高端的存储设备,更换更高端CPU,更换转速更快的磁盘…) 向外扩展(Scale Out) 数据拷贝分发(一处写入多处读取,读写分离…) 数据垂直/水平切分(功能模块切分(vertical sharding),水平分片切分(horizontal sharding),两者综合) Cache 和 Search(应用程序更新Cache,数据库更新 […]

, , , ,

这几天看了不少Google针对于MySQL开发的google-mysql-tools,找到一个很有意思的Patch:MirroredBinlogs。 这个Patch通过修改MySQL Replication中Slave IO线程的实现,让该线程在写入relay log的同时,再Mirror了一份与Master端完全一模一样binlog。这里所说的一模一样不仅仅是binlog的内容完全一样,同时还包括binlog的文件名。也就是说,该线程在Slave端完全copy了一份Master的binlog日志。 在该 Patch 的描述中,该 Patch 产生的初衷是为了解决Slave与Master之前的顺利切换,并保证切换之后其他Slave仍然能够正常从新的Master继续进行复制。 作者设想了如下一个场景: 在 Hierarchical Replication(级联复制)环境中,第一层是有一台 Master ,第二层是两台 Slaves ,这两台Slave主要作用是作为第三层更多 Slave 的 Master 。也就是,第二层的两台 Slave 的角色在整个集群环境中是一个复制代理。如果我们使用的是普通的MySQL,那么中间代理层的两台Slave之间的binlog日志可能会有较大差异,因为两台Slave自身也会有产生binlog的event。而通过使用该Patch之后,通过 Slave IO 线程将第一层中 Master 的binlog完全一模一样的copy到第二层的 Slave 上面,而使这一层的binlog完全一致。这样,当第二层的两台复制代理机器中的一台Crash之后,可以很容易的将第三层中以 前面 Crash 的 Slave 作为 Master 的所有 Slave 可以很容易的切换 Master 到另外一台 代理 Slave 上面。 只不过,开发者已经停止了该Patch的更新,并将该Patch整合到了一个新的叫 GlobalTransactionIds(MySQL Hierarchical Replication & Global Group IDs)的Patch中,只不过该Patch还正在开发中。从 Google 在 […]

, , ,

1、复制进程 Mysql的复制(replication)是一个异步的复制,从一个Mysql instace(称之为Master)复制到另一个Mysql instance(称之Slave)。实现整个复制操作主要由三个进程完成的,其中两个进程在Slave(Sql进程和IO进程),另外一个进程在Master(IO进程)上。 要实施复制,首先必须打开Master端的binary log(bin-log)功能,否则无法实现。因为整个复制过程实际上就是Slave从Master端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。 复制的基本过程如下: 1)、Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容; 2)、Master接收到来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置; 3)、Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的高速Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”; 4)、Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行。 实际上在老版本的Mysql的复制实现在Slave端并不是两个进程完成的,而是由一个进程完成。但是后来发现这样做存在较大的风险和性能问题,主要如下: 首先,一个进程就使复制bin-log日志和解析日志并在自身执行的过程成为一个串行的过程,性能受到了一定的限制,异步复制的延迟也会比较长。 另外,Slave端从Master端获取bin-log过来之后,需要接着解析日志内容,然后在自身执行。在这个过程中,Master端可能又产生了大量变化并声称了大量的日志。如果在这个阶段Master端的存储出现了无法修复的错误,那么在这个阶段所产生的所有变更都将永远无法找回。如果在Slave端的压力比较大的时候,这个过程的时间可能会比较长。 所以,后面版本的Mysql为了解决这个风险并提高复制的性能,将Slave端的复制改为两个进程来完成。提出这个改进方案的人是Yahoo!的一位工程师“Jeremy Zawodny”。这样既解决了性能问题,又缩短了异步的延时时间,同时也减少了可能存在的数据丢失量。当然,即使是换成了现在这样两个线程处理以后,同样也还是存在slave数据延时以及数据丢失的可能性的,毕竟这个复制是异步的。只要数据的更改不是在一个事物中,这些问题都是会存在的。如果要完全避免这些问题,就只能用mysql的cluster来解决了。不过mysql的cluster是内存数据库的解决方案,需要将所有数据都load到内存中,这样就对内存的要求就非常大了,对于一般的应用来说可实施性不是太大。 2、复制实现级别 Mysql的复制可以是基于一条语句(Statement level),也可以是基于一条记录(Row level),可以在Mysql的配置参数中设定这个复制级别,不同复制级别的设置会影响到Master端的bin-log记录成不同的形式。 Row Level:日志中会记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修改。 优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条记录被修改了,修改成什么样了。所以row level的日志内容会非常清楚的记录下每一行数据修改的细节,非常容易理解。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题。 缺点:row level下,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如有这样一条update语句:update product set owner_member_id = ‘b’ where owner_member_id = ‘a’,执行之后,日志中记录的不是这条update语句所对应额事件(mysql以事件的形式来记录bin-log日志),而是这条语句所更新的每一条记录的变化情况,这样就记录成很多条记录被更新的很多个事件。自然,bin-log日志的量就会很大。尤其是当执行alter table之类的语句的时候,产生的日志量是惊人的。因为Mysql对于alter table之类的表结构变更语句的处理方式是整个表的每一条记录都需要变动,实际上就是重建了整个表。那么该表的每一条记录都会被记录到日志中。 Statement Level:每一条会修改数据的sql都会记录到 master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行。 优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能。因为他只需要记录在Master上所执行的语句的细节,以及执行语句时候的上下文的信息。 缺点:由于他是记录的执行语句,所以,为了让这些语句在slave端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端杯执行的时候能够得到和在master端执行时候相同的结果。另外就是,由于Mysql现在发展比较快,很多的新功能不断的加入,使mysql得复制遇到了不小的挑战,自然复制的时候涉及到越复杂的内容,bug也就越容易出现。在statement level下,目前已经发现的就有不少情况会造成mysql的复制出现问题,主要是修改数据的时候使用了某些特定的函数或者功能的时候会出现,比如:sleep()函数在有些版本中就不能真确复制,在存储过程中使用了last_insert_id()函数,可能会使slave和master上得到不一致的id等等。由于row level是基于每一行来记录的变化,所以不会出现类似的问题。 从官方文档中看到,之前的Mysql一直都只有基于statement的复制模式,直到5.1.5版本的Mysql才开始支持row level的复制。从5.0开始,Mysql的复制已经解决了大量老版本中出现的无法正确复制的问题。但是由于存储过程的出现,给Mysql的复制又带来了更大的新挑战。另外,看到官方文档说,从5.1.8版本开始,Mysql提供了除Statement Level和Row Level之外的第三种复制模式:Mixed,实际上就是前两种模式的结合。在Mixed模式下,Mysql会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。新版本中的Statment level还是和以前一样,仅仅记录执行的语句。而新版本的Mysql中队row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。 3、复制常用架构 Mysql复制环境90%以上都是一个Master带一个或者多个Slave的架构模式,主要用于读压力比较大的应用的数据库端廉价扩展解决方案。因为只要master和slave的压力不是太大(尤其是slave端压力)的话,异步复制的延时一般都很少很少。尤其是自slave端的复制方式改成两个进程处理之后,更是减小了slave端的延时。而带来的效益是,对于数据实时性要求不是特别的敏感度的应用,只需要通过廉价的pc […]

, , ,