证券行业首个混合金融云面世,海通证券”信息化”探索之路再领先一步

“集团化、国际化、信息化”是海通证券近年来的发展方向。科技战略作为海通的“四根支柱”之一,打造自主可控的金融云成为公司建设智慧海通、实现科技战略的重要一环。历经三年的探索与实践,海通证券金融云从单一的VMware资源池到开源OpenStack+公有云混合资源池、从单一的集中式存储池到开源分布式存储池再到容量/性能混合存储池、从传统网络架构到新一代SDN云网架构、从研发测试环境试点到生产环境大范围推广,进而打造了中国证券行业首个自主可控的统一纳管、编排私有云资源池、行业云资源池和公有云资源池的混合基础设施服务平台。海通证券在混合金融云方案上的积极探索与实践使得业务价值进一步释放,不但引领了证券行业金融云发展,更是整个证券行业数字化转型过程的探索和创新先行者。

作为国内成立最早、实力最强、规模最大的综合性券商之一,海通证券从1988年创立至今,一直处在行业内的领军阵营,不断发展壮大,迄今公司总资产近6000亿元、净资产近1200亿元,位居国内证券行业前列,经营网点遍及全球14个国家和地区,境内拥有近340家证券及期货经纪营业网点,境内外拥有近1300万零售及机构和高净值客户。

海通证券积极拥抱金融科技的发展浪潮

伴随着互联网金融的快速发展和普惠金融的深入落地,金融科技能力成为传统金融企业支持未来业务发展、实现企业数字化转型的核心能力。在此背景下,IT逐渐从后台走向前台,IT服务能力和管理水平直接影响着企业核心竞争力的打造。作为中国综合性证券机构的龙头企业,海通证券积极拥抱金融科技的发展浪潮,坚持“统一管理、自主可控、融合业务、引领发展”的科技指导思想,并率先在证券行业启动金融云的建设规划。

稳步建设海通证券金融云:2016年,海通证券发布了《海通证券2016-2020年科技发展规划》,明确了要把“稳步建设海通金融云”作为今后5年科技发展规划的战略任务之一,并采用开源虚拟化和软件定义技术,建立计算、网络、存储资源池,实现基础设施资源共享和自动化管理,为生产、测试、研发环境提供按需服务、按需计量能力;采用容器相关技术,实现生产、测试、研发环境应用构件的快速部署,提高系统可用性和部署效率。

明确定位海通证券金融云:在符合合规性、安全性、可用性的前提下,通过使用开源OpenStack框架,打造具有一定服务能力和金融架构特征的从IaaS到PaaS到SaaS的金融云平台。在此平台基础上,立足海通证券的经纪业务、投资业务、资管业务,发挥海通证券在证券行业龙头地位的优势,在利用技术平台进行业务能力输出的同时加强海通证券金融生态能力的建设,进一步构建上下游业务、资金、风险、信用等信息的分享和交换平台。

大胆描绘海通证券金融云:围绕公司战略发展规划和业务驱动,结合行业发展趋势,海通证券基于开源技术架构,通过开放合作和自主研发相结合的规划目标,制定了“五年五朵云”的金融云蓝图,目前办公云、研发测试云、生产云均已顺利上线并大范围使用。未来将有序开展托管云和行业云的建设工作,从而更好的为子公司、分公司提供高效便捷的服务,进一步释放集团化业务能力。

行业领先的混合金融云架构助力数字化转型

基础设施建设是数字化转型的基础。海通证券率先使用云管理平台(CMP)统一服务入口、开源OpenStack核心技术自主可控、国产硬件SDN网络智能运维、多后端存储资源池按需交付的金融云架构,充分展现了敏捷自动化、稳定高可用、可弹性扩展、可智能运维等一系列技术优势,引领证券行业金融云发展,同时也在多方面进行了创新。

异构纳管、统一编排:为了更好的支撑业务创新,海通证券基础设施资源池一直不断延展,既有大量的物理机资源池,又有基于X86服务器和超融合一体机的VMWare虚拟化资源池;既有多套基于X86服务器和开源分布式架构的OpenStack私有云资源池,又有基于上证信息和深证通的行业云资源池和基于阿里云、腾讯云和华为云等厂商的公有云资源池。海通证券混合金融云平台不但实现了对多种异构资源池的统一纳管,也形成了异构资源池的业务流程编排、IT资源成本分析与管理体系,这不仅仅是混合IT资源纳管的范畴和能力的提升,更是标志着海通混合金融云进入了一个自助交付、智能运营的新阶段。

基于开源、自主可控:为了全面贯彻习总书记提出的“关键核心技术自主可控,把创新主动权、发展主动权牢牢掌握在自己手中”的指导思想,海通证券从一开始就坚持要走开源、开放的技术路线。海通证券基于开源OpenStack的金融云平台不但满足金融云自主可控、稳定安全的诉求,同时其健全庞大的生态体系、分享开放的社区模式也有利于持续赋能技术团队,打造业务和技术兼备的综合型人才。在架构设计上海通证券采用了Multi-Region物理隔离和多可用区域(AZ)逻辑分区相结合的高可用方案,为后续云平台的大规模扩展、“两地三中心”的应用交付打下坚实的基础。

云网联动、融合业务:数字化转型离不开信息技术架构的创新,海通证券金融云新一代云网整体架构引入了国产硬件SDN方案,实现了云网联动,使得网络和安全策略可以随业务自动化下发与配置。SDN网络实现了面向应用的网络编排,基于不同业务组的定义,实现不同业务组间的策略编排。当计算资源发生变更时,网络策略自动迁移,无需人工参与,减少了网络人员变更端口配置的重复劳动,网络人员更可聚焦网络优化和自动化运维的工作。Fabric网络采用Spine-Leaf架构,通过VxLAN技术构建分布式组网架构,可以支持业务灵活扩展,极大增强了网络可靠性和扩展性,实现应用业务间高性能互访、虚拟机灵活迁移、网络资源自动适配。

性能容量、各取所长:随着在金融云环境上的应用场景不断丰富、数据量持续增长,数据来源呈现多样性,业务应用对数据可用性、性能的要求也不尽相同。在海通证券金融云架构中,根据业务需求不同,按资源类型分别提供了开源分布式存储资源池和集中式存储资源池;按资源性能分别提供了“超大容量存储资源池”“混合存储资源池”和“超高性能存储资源池”。通过对不同性能的存储资源进行池化封装、定义标签,并建立放置策略,从而有效的满足了敏态和稳态并存的业务应用,进一步确保了海通金融云的高效运营与服务交付,为用户提供极佳的使用体验。

行稳致远持续创新

海通证券生产云的落地,标志着海通证券拥有足够的能力驾驭云计算相关技术,标志着海通证券金融云进入了一个更具挑战、需承担更多责任的新阶段。着眼未来,海通证券将继续发挥综合性龙头券商的优势,积极探索和实践容器相关技术、应用微服务化架构、SDN网络智能分析与运维等多项创新应用,为实现从“科技支撑业务”到“科技引领业务”的数字化转型奠定基础,从而进一步引领云计算技术在证券行业的应用和发展。

DataGuard 理论知识

DataGuard 理论知识
1. Oracle的高级特性:
1. RAC, Data Gurad, Stream是Oracle高可用性体系中的三种工具,每个工具既可以独立应用,也可以相互配合,它们各自的侧重点不同,适用场景也不同;
2. RAC它的强项在于解决硬件单点故障和负载均衡,因此RAC方案常用于7*24的核心系统,但RAC方案中的数据只有一份,尽管可以通过RAID等机制避免存储故障,但是数据本身是没有冗余的,容易形成数据的单点故障;
3. Data Gurad通过冗余数据来提供数据保护,Data Gurad通过日志同步机制保证冗余数据和主数据之前的同步,这种同步可以是实时,延时,同步,异步多种形式.Data Gurad常用于异地容灾和小企业的高可用性方案,虽然可以在Standby机器上执行只读查询,从而分散Primary数据库的性能压力,但是Data Gurad决不是性能解决方案;
4. Stream是以Oracle Advanced Queue为基础实现的数据同步,提供了多种级别的灵活配置,并且Oracle提供了丰富的API等开发支持,Stream更适用在应用层面的数据共享.现在已经被Oracle GlodenGate工具取代;
2. DataGuard的原理及优点:
1. 在Data Gurad环境中,至少有两个数据库,一个处于Open状态对外提供服务,这个数据库叫作Primary Database.第二个处于恢复状态,叫作Standby Database.运行时primary Database对外提供服务,用户在Primary Database上进行操作,操作被记录在联机日志和归档日志中,这些日志通过网络传递给Standby Database.这个日志会在Standby Database上重演,从而实现Primary Database 和Standby Database 的数据同步;
2. Oracle Data Gurad对这一过程进一步的优化设计,使得日志的传递,恢复工作更加自动化,智能化,并且提供一系列参数和命令简化了DBA工作.如果是可预见因素需要关闭Primary Database,比如软硬件升级,可以把 Standby Database切换为Primary Database继续对外服务,这样即减少了服务停止时间,并且数据不会丢失.如果异常原因导致Primary Database不可用,也可以把Standby Database强制切换为Primary Database继续对外服务 ,这时数据损失成都和配置的数据保护级别有关系.因此Primary和Standby只是一个角色概念,并不固定在某个数据库中;
3. DataGuard结构:
1. DG架构可以按照功能分成3个部分:
1. 日志发送 (Redo Send);
2. 日志接收 (Redo Receive);
3. 日志应用 (Redo Apply);
2. 日志发送(Redo Send):
1. Primary Database运行过程中,会源源不断地产生Redo日志,这些日志需要发送到Standy Database.这个发送动作可以由Primary Database的LGWR或者ARCH进程完成,不同的归档目的地可以使用不同的方法,但是对于一个目的地,只能选用一种方法.选择哪个进程对数据保护能力和系统可用性有很大区别;
2. 使用ARCH进程:
1. Primary Database不断产生Redo Log,这些日志被LGWR进程写到联机日志;
2. 当一组联机日志被写满后,会发生日志切换(Log Switch),并且会触发本地归档,本地归档位置是采用LOG_ARCHIVE_DEST_1=’LOCATION=/path’这种格式定义的;
3. 完成本地归档后,联机日志就可以被覆盖重用;
4. ARCH进程通过Net把归档日志发送给Standby Database的RFS(Remote File Server)进程;
5. Standby Database端的RFS进程把接收的日志写入到归档日志(用ARCH模式传输不写Standby Redologs,直接保存成归档日志文件存放于Standby端);
6. Standby Database端的MRP(Managed Recovery Process)进程(Redo Apply)或者LSP进程(SQL Apply)在Standby Database上应用这些日志,进而同步数据;
1. 逻辑Standby接收后将其转换成SQL语句,在Standby数据库上执行SQL语句实现同步,这种方式叫SQL Apply;
2. 物理Standby接收完Primary数据库生成的REDO数据后,以介质恢复的方式实现同步,这种方式也叫Redo Apply;
3. 创建逻辑Standby数据库要先创建一个物理Standby数据库,然后再将其转换成逻辑Standby数据库;
7. 使用ARCH进程传递最大问题在于:Primary Database只有在发生归档时才会发送日志到Standby Database.如果Primary Database异常宕机,联机日志中的Redo内容就会丢失,因此使用ARCH进程无法避免数据丢失的问题,要想避免数据丢失,就必须使用LGWR,而使用LGWR又分SYNC(同步)和ASYNC(异步)两种方式;
8. 在缺省方式下,Primary Database使用的是ARCH进程;
3. 使用LGWR进程的SYNC方式:
1. Primary Database产生的Redo日志要同时写到联机日志文件和网络.也就是说LGWR进程把日志写到本地日志文件的同时还要发送给本地的LNSn进程(LGWR Network Server Process),再由LNSn进程把日志通过网络发送给远程的目的地,每个远程目的地对应一个LNS进程,多个LNS进程能够并行工作;
2. LGWR必须等待写入本地联机日志文件操作和通过LNSn进程的网络传送都成功,Primary Database上的事务才能提交,这也是SYNC的含义所在;
3. Standby Database的RFS进程把接收到的日志写入到Standby Redo Log日志中;
4. Primary Database的日志切换也会触发Standby Database上的日志切换,即Standby Database对Standby Redo Log的归档,然后触发Standby Database的MRP或者LSP进程恢复归档日志;
5. 因为Primary Database的Redo是实时传递的,于是Standby Database端可以使用两种恢复方法:
1. 实时恢复(Real-Time Apply):只要RFS把日志写入Standby Redo Log就会立即进行恢复;
2. 归档恢复:在完成对Standby Redo Log归档才触发恢复;
6. Primary Database默认使用ARCH进程,如果使用LGWR进程必须明确指定.使用LGWR SYNC方式时,可以同时使用NET_TIMEOUT参数,这个参数单位是秒,代表如果多长时间内网络发送没有响应,LGWR进程会抛出错误.如:ALTER SYSTEM SET LOG_ARCHIVE_DEST_2 = ‘SERVICE= LGWR SYNC NET_TIMEOUT=30′ SCOPE = BOTH;
4. 使用LGWR进程的ASYNC方式:
1. 使用LGWR SYNC方法的可能问题在于,如果日志发送给Standby Database过程失败,LGWR进程就会报错.也就是说Primary Database的LGWR进程依赖于网络状况,有时这种要求可能过于苛刻,这时就可以使用LGWR ASYNC方式;
2. Primary Database一段产生Redo日志后,LGWR把日志同时提交给日志文件和本地LNS进程,但是LGWR进程只需成功写入日志文件就可以,不必等待LNSn进程的网络传送成功;
3. LNSn进程异步地把日志内容发送到Standby Database.多个LNSn进程可以并发发送;
4. Primary Database的Online Redo Log写满后发生Log Switch,触发归档操作,也触发Standby Database对Standby Database对Standby Redo Log的归档,然后触发MRP或者LSP进程恢复归档日志;
5. 因为LGWR进程不会等待LNSn进程的响应结果,所以配置LGWR ASYNC方式时不需要NET_TIMEOUT参数.如:ALTER SYSTEM SET LOG_ARCHIVE_DEST_2 = ‘SERVICE=
LGWR ASYNC’ SCOPE = BOTH;
3. 日志接收(Redo Receive):
1. Standby Database的RFS(Remote File Server)进程接收到日志后,就把日志写到Standby Redo Log或者Archived Log文件中,具体写入哪个文件,取决于Primary的日志传送方式和Standby database的位置;
2. 如果写到Standby Redo Log文件中,则当Primary Database发生日志切换时,也会触发Standby Database上的Standby Redo Log的日志切换,并把这个Standby Redo Log归档.如果是写到Archived Log,那么这个动作本身也可以看作是个归档操作;
3. 在日志接收中,需要注意的是归档日志会被放在什么位置:
1. 如果配置了STANDBY_ARCHIVE_DEST参数,则使用该参数指定的目录;
2. 如果某个LOG_ARCHIVE_DEST_n参数明确定义了VALID_FOR=(STANDBY_LOGFILE,*)选项,则使用这个参数指定的目录;
3. 如果数据库的COMPATIBLE参数大于等于10.0,则选取任意一个LOG_ARCHIVE_DEST_n的值;
4. 如果STANDBY_ARCHIVE_DEST和LOG_ARCHIVE_DEST_n参数都没有配置,使用缺省的STANDBY_ARCHIVE_DEST参数值,这个缺省值是$ORACLE_HOME/dbs/arc;
4. 日志应用(Redo Apply):
1. 日志应用服务,就是在Standby Database上重演Primary Database日志,从而实现两个数据库的数据同步;
2. 根据Standby Database重演日志方式的不同,可分为物理Standby(Physical Standby)和逻辑Standby(Logical Standby):
1. Physical Standby使用的是Media Recovery技术,在数据块级别进行恢复,这种方式没有数据类型的限制,可以保证两个数据库完全一致;Physical Standby数据库只能在Mount状态下进行恢复,也可以是打开,但只能已只读方式打开,并且打开时不能执行恢复操作;
2. Logical Standby使用的是Logminer技术,通过把日志内容还原成SQL语句,然后SQL引擎执行这些语句,Logminer Standby不支持所有数据类型,可以在视图DBA_LOGSTDBY_UNSUPPORTED中查看不支持的数据类型,如果使用了这种数据类型,则不能保证数据库完全一致;Logical Standby数据库可以在恢复的同时进行读写操作;
3. Standby数据库的相关进程读取接收到的REDO数据(可能来自于Standby端的归档文件,也可能来自于Standby Redologs),再将其写入Standby数据库.保存之后数据又是怎么生成的呢?两种方式:物理Standby通过REDO应用,逻辑Standby通过SQL应用;
4. 根据Redo Apply发生的时间可以分成两种:
1. 实时应用(Real-Time Apply):这种方式必须Standby Redo Log,每当日志被写入Standby Redo Log时,就会触发恢复,使用这种方式的好处在与可以减少数据库切换(Switchover或者Failover)的时间,因为切换时间主要用在剩余日志的恢复上;
2. 归档时应用,这种方式在Primary Database发生日志切换,触发Standby Database归档操作,归档完成后触发恢复,这也是默认的恢复方式;
3. 如果是Physical Standby,可以使用下面命令启用Real-Time:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE;
4. 如果是Logical Standby,可以使用下面命令启用Real-Time:ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
5. 查看是否使用Real-Time apply:SELECT RECOVERY_MODE FROM v$archive_dest_status;
6. 查看Standby Database接收日志的状态:SELECT process, status, thread#, sequence#, client_pid FROM v$managed_standby;
4. 数据保护模式:
1. Data Guard允许定义3种数据保护模式,分别是最大保护(Maximum Protection),最大可用(Maximum Availability)和最大性能(Maximum Performance);
2. 最大保护(Maximum Protection):
1. 这种模式能够确保绝无数据丢失.要实现这一步当然是有代价的,它要求所有的事务在提交前其REDO不仅被写入到本地的Online Redologs,还要同时写入到Standby数据库的Standby Redologs,并确认REDO数据至少在一个Standby数据库中可用(如果有多个的话),然后才会在Primary数据库上提交.如果出现了什么故障导致Standby数据库不可用的话(比如网络中断),Primary数据库会被Shutdown,以防止数据丢失;
2. 使用这种方式要求Standby Database必须配置Standby Redo Log,而Primary Database必须使用LGWR,SYNC,AFFIRM方式归档到Standby Database;
3. 最高可用性(Maximum availability):
1. 这种模式在不影响Primary数据库可用前提下,提供最高级别的数据保护策略.其实现方式与最大保护模式类似,也是要求本地事务在提交前必须至少写入一台Standby数据库的Standby Redologs中,不过与最大保护模式不同的是,如果出现故障导致Standby数据库无法访问,Primary数据库并不会被Shutdown,而是自动转为最高性能模式,等Standby数据库恢复正常之后,Primary数据库又会自动转换成最高可用性模式;
2. 这种方式虽然会尽量避免数据丢失,但不能绝对保证数据完全一致.这种方式要求Standby Database必须配置Standby Redo Log,而Primary Database必须使用LGWR,SYNC,AFFIRM方式归档到Standby Database;
4. 最高性能(Maximum performance):
1. 缺省模式,这种模式在不影响Primary数据库性能前提下,提供最高级别的数据保护策略.事务可以随时提交,当前Primary数据库的REDO数据至少需要写入一个Standby数据库,不过这种写入可以是不同步的.如果网络条件理想的话,这种模式能够提供类似最高可用性的数据保护,而仅对Primary数据库的性能有轻微影响.这也是创建Standby数据库时,系统的默认保护模式;
2. 这种方式可以使用LGWR ASYNC或者ARCH进程实现,Standby Database也不要求使用Standby Redo Log;
5. 修改数据保护模式步骤:
1. 关闭数据库,重启到Mount状态,如果是RAC,需要关闭所有实例,然后只启动一个实例到mount状态;
2. 修改到日志传输参数:ALTER SYSTEM SET LOG_ARCHIVE_DEST_2 = ‘SERVICE=
LGWR SYNC|ASYNC AFFIRM|NOAFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=‘;
3. 修改模式:ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE {PROTECTION | AVAILABILITY | PERFORMANCE};
4. 打开数据库:ALTER DATABASE OPEN;
5. 确认修改数据保护模式:SELECT protection_mode, protection_level FROM v$database;
5. 自动裂缝检测和解决:
1. 当Primary Database的某些日志没有成功发送到Standby Database,这时候发生饿了归档裂缝(Archive Gap);
2. 缺失的这些日志就是裂缝(Gap).Data Guard能够自动检测,解决归档裂缝,不需要DBA的介入.这需要配置FAL_CLIENT,FAL_SERVER这两个参数(FAL:Fetch Archive Log);
3. 从FAL这个名字可以看出,这个过程是Standby Database主动发起的”取”日志的过程,Standby Database就是FAL_CLIENT.它是从FAL_SERVER中取这些Gap,10g中,这个FAL_SERVER可以是Primary Database, 也可以是其它的Standby Database;如:FAL_SERVER=’PR1,ST1,ST2’;
4. FAL_CLIENT和FAL_SERVER两个参数都是Oracle Net Name.FAL_CLIENT通过网络向FAL_SERVER发送请求,FAL_SERVER通过网络向FAL_CLIENT发送缺失的日志.但是这两个连接不一定是一个连接.因此FAL_CLIENT向FAL_SERVER发送请求时,会携带FAL_CLIENT参数值,用来告诉 FAL_SERVER应该向哪里发送缺少的日志.这个参数值也是一个Oracle Net Name,这个Name是在FAL_SERVER上定义的,用来指向FAL_CLIENT;
5. DBA也可以手工解决,具体操作步骤如下:
1. 查看是否有日志GAP:SELECT UNIQUE THREAD#, MAX(SEQUENCE#) OVER(PARTITION BY THREAD#) LAST FROM V$ARCHIVED_LOG;
2. SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
3. 如果有,则拷贝过来;
4. 手工的注册这些日志:ALTER DATABASE REGISTER LOGFILE ‘/path’;
6. 指定日志发送对象:
1. VALID_FOR属性指定传输及接收对象:
1. LOG_ARCHIVE_DEST_n参数中的VALID_FOR属性,用来指定传输的内容.从字面理解VALID_FOR就是基于哪些有效;
2. 该属性有两个参数值需要指定:REDO_LOG_TYPE和DATABASE_ROLE,我们基本上可以将其理解为:发送指定角色生成的指定类型的日志文件,该参数的主要目的是为了确保一旦发生角色切换操作后数据库的正常运转;
1. REDO_LOG_TYPE:可设置为ONLINE_LOGFILE,STANDBY_LOGFILE,ALL_LOGFILES;
2. DATABASE_ROLE:可设置为PRIMARY_ROLE,STANDBY_ROLE,ALL_ROLES;
3. VALID_FOR参数默认值是VALID_FOR=(ALL_LOGFILES,ALL_ROLES);
4. 推荐手动设置该参数而不要使用默认值,在某些情况下默认的参数值不一定合适,如逻辑Standby在默认情况下就处于OPEN READ WRITE模式,不仅有REDO数据而且还包含多种日志文件(Online Redologs,Archived Redologs,Standby Redologs);
5. 默认情况下,逻辑Standby数据库生成的归档文件和接收到的归档文件在相同的路径下,这既不便于管理,也极有可能带来一些隐患.建议对每个LOG_ARCHIVE_DEST_n参数设置合适的VALID_FOR属性.本地生成的归档文件和接收到的归档文件最好分别保存于不同路径下;
2. 通过DB_UNIQUE_NAME属性指定数据库:
1. DB_UNIQUE_NAME属性是10g版本新增加的一个关键字,在之前版本并没有这一说法.该属性的作用是指定唯一的Oracle数据库名称,也正因有了DB_UNIQUE_NAME,REDO数据在传输过程中才能确认传输到 DBA希望被传输到的数据库上;
2. 当然要确保REDO数据被传输到指定服务器,除了在LOG_ARCHIVE_DEST_n参数中指定正确 DB_UNIQUE_NAME属性之外,还有一个初始化参数LOG_ARCHIVE_CONFIG也需要进行正确的配置;
3. 该参数除了指定 Data Guard环境中的唯一数据库名外,还包括几个属性,用来控制REDO数据的传输和接收:
1. SEND:允许数据库发送数据到远端;
2. RECEIVE:允许Standby接收来自其它数据库的数据;
3. NOSEND,NORECEIVE:就是禁止喽;
4. 设置Primary数据库不接收任何归档数据,可以做如下的设置:LOG_ARCHIVE_CONFIG=’NORECEIVE,DG_CONFIG=(,,…)’;
5. 如果做了如上的设置,如果该服务器发生了角色切换,那它也没有接收REDO数据的能力;
7. Data Guard环境应配置的初始化参数:
1. Primary角色相关的初始化参数:
1. DB_NAME:要保持同一个Data Guard中所有数据库DB_NAME相同;
2. DB_UNIQUE_NAME:为每一个数据库指定一个唯一的名称,该参数一经指定不会再发生变化,除非DBA主动修改它,需要重启数据库服务;
3. LOG_ARCHIVE_CONFIG:该参数用来控制从远端数据库接收或发送REDO数据,通过DG_CONFIG属性列出同一个Data Guard中所有DB_UNIQUE_NAME(含Primary数据库和Standby数据库),以逗号分隔;
1. SEND/NOSEND属性控制是否可以发送;
2. RECEIVE/NORECEIVE属性控制是否能够接收;
3. 例如:LOG_ARCHIVE_CONFIG=’DG_CONFIG=(,,…)’;
4. LOG_ARCHIVE_DEST_n:归档文件的生成路径,该参数非常重要,并且属性和子参数也特别多:
1. LOCATOIN|SERVICE:指定目标是本地还是网络位置;
2. MANDATORY|OPTIONAL:指定是否强制写到目标位置,默认是OPTIONAL;
3. DELAY(mins):指定间隔多久应用接收到的日志,默认是30Mins;
4. ARCH|LGWR:指定使用ARCH进程传输归档日志还是LGWR进程传输在线联机日志,默认是ARCH;
5. SYNC|ASYNC:指定是同步把redo log同步写到备机还是异步写,默认是ASYNC;
6. AFFIRM|NOAFFIRM:指定RTS(Redo Transport Service)使用同步还是异步方式写磁盘,缺省是NOARRIRM;
7. NET_TIMEOUT(s):指定超时时间,默认是180s;
8. VALID_FOR:指定传输及接受对象;
9. DB_UNIQUE_NAME:指定目标数据库的unique name;
10. REOPEN指定时间后再次尝试归档:
1. 使用REOPEN=seconds(默认为300秒)属性,在指定时间重复尝试向归档目的地进行归档操作,如果该参数值设置为0,则一旦失败就不会再尝试重新连接并发送,直到下次REDO数据再被归档时会重新尝试;
2. 例如,设置 REOPEN为100 秒:LOG_ARCHIVE_DEST_2=’SERVICE=DavePrimary LGWR ASYNC REOPEN=100′;
11. ALTERNATE指定替补的归档目的地:ALTERNATE属性定义一个替补的归档目的地,所谓替补就是一旦主归档目的地因各种原因无法使用,则临时向ALTERNATE属性中指定的路径写;
1. 例如:LOG_ARCHIVE_DEST_1=’LOCATION=/disk1 ALTERNATE=LOG_ARCHIVE_DEST_2′;
2. LOG_ARCHIVE_DEST_STATE_1=ENABLE;
3. LOG_ARCHIVE_DEST_2=’LOCATION=/disk2′;
4. LOG_ARCHIVE_DEST_STATE_2=ALTERNATE;
5. 上述参数设置归档路径为/disk1,当/disk1路径下无法成功归档时,自动尝试向/disk2路径下归档文件;
12. 从功能上来看,REOPEN与ALTERNATE是有一定重复的,不过需要注意一点,REOPEN属性比ALTERNATE属性的优先级要高,如果你指定REOPEN属性的值>0,则LGWR(或ARCn)进程会首先尝试向主归档目的地写入,直到达到最大重试次数,如果仍然写入失败,才会向ALTERNATE属性指定的路径写;
13. MAX_FAILURE控制失败尝试次数:
1. 用REOPEN指定失败后重新尝试的时间周期,MAX_FAILURE则控制失败尝试的次数;
2. 例如,设置 LOG_ARCHIVE_DEST_1在本地归档文件时,如果遇到错误,则每隔100秒尝试一次,共尝试不超过3次,设置如下:LOG_ARCHIVE_DEST_1=’LOCATION=E:/ora10g/oradata/jsspdg/ REOPEN=100 MAX_FAILURE=3′;
5. LOG_ARCHIVE_DEST_STATE_n:是否允许REDO传输服务传输REDO数据到指定的路径:
1. ENABLED:开启传输,默认值;
2. DEFER:阻止传输;
3. ALTERNATE:默认是阻止,当其它路径失败后被激活;
4. RESET:重置;
6. REMOTE_LOGIN_PASSWORDFILE:推荐设置参数值为EXCLUSIVE或者SHARED,注意保证相同Data Guard配置中所有DB服务器SYS密码相同;
2. Standby角色相关的参数(建议在Primary数据库的初始化参数中也进行设置,这样即使发生角色切换,新的Standby也能直接正常运行):
1. FAL_SERVER:指定一个Net服务名,该参数值对应的数据库应为Primary角色.当本地数据库为Standby角色时,如果发现存在归档中断的情况,该参数用来指定获取中断的归档文件的服务器;FAL_SERVER参数支持多个参数值,相互间以逗号分隔;
2. FAL_CLIENT:又指定一个Net服务名,该参数对应数据库应为Standby角色.当本地数据库以Primary角色运行时,向参数值中指定的站点发送中断的归档文件;FAL_CLIENT参数也支持多个参数值,相互间以逗号分隔;
3. DB_FILE_NAME_CONVERT:Standby数据库的数据文件路径与Primary数据库数据文件(包括临时表空间和UNDO表空间)路径不一致时,可以通过设置DB_FILE_NAME_CONVERT参数的方式让其自动转换.该参数值应该成对出现,前面的值表示转换前的形式,后面的值表示转换后的形式;例如:DB_FILE_NAME_CONVERT=‘/path1’,’/path2′;
4. LOG_FILE_NAME_CONVERT:使用方式与上相同,只不过LOG_FILE_NAME_CONVERT专用来转换日志文件路;
5. STANDBY_FILE_MANAGEMENT:Primary数据库数据文件发生修改(如新建,删除等)则按照本参数的设置在Standby数据库中作相应修改.设为AUTO表示自动管理.设为MANUAL表示需要手工管理;
8. 物理Standby和逻辑Standby的区别:
1. 物理Standby:
1. 我们知道物理Standby与Primary数据库完全一模一样,DG通过REDO应用来维护物理Standby数据库;
2. 通常在物理Standby没有执行REDO应用操作的时候,可以将物理Standby数据库以READ ONLY模式打开,如果数据库中指定了Flashback Area的话,甚至还可以被临时性的置为READ WRITE模式,操作完之后再通过Flashback Database特性恢复回READ WRITE前的状态,以便继续接收Primary端发送的REDO并应用;
3. REDO应用:物理Standby通过REDO应用来保持与Primary数据库的一致性,所谓的REDO应用,实质是通过Oracle的恢复机制,应用归档文件(或Standby Redologs文件)中的REDO数据.恢复操作属于块对块的应用.如果正在执行REDO应用的操作,Oracle数据库就不能被Open;
4. READ ONLY模式打开:以READ ONLY模式打开后,可以在Standby数据库执行查询或备份等操作(变相减轻Primary数据库压力).此时Standby数据库仍然能够继续接收Primary数据库发送的REDO数据,不过并不会应用,直到Standby数据库重新恢复REDO应用;
5. 也就是说在READ ONLY模式下不能执行REDO应用,REDO应用时数据库肯定处于未打开状态.如果需要的话,你可以在两种状态间转换,如先应用REDO,然后将数据库置为READ ONLY状态,需要与Primary同步时再次执行 REDO应用命令,切换回REDO应用状态;
6. Oracle 11g版本中增强物理Standby的应用功能,在11g版本中,物理Standby可以在OPEN READ ONLY模式下继续应用REDO数据,这就极大地提升了物理Standby数据库的应用场合;
7. READ WRITE模式打开:如果以READ WRITE模式打开,那么Standby数据库将暂停从Primary数据库接收REDO数据,并且暂时失去灾难保护的功能.当然,以READ WRITE模式打开也并非一无是处,如你可能需要临时调试一些数据,但又不方便在正式库中操作,那就可以临时将Standby数据库置为READ WRITE模式,操作完之后将数据库闪回到操作前的状态(闪回之后,Data Guard会自动同步,不需要重建物理Standby,不过如果从另一个方向看,没有启动闪回,那就回不到READ WRITE前的状态了);
8. 物理Standby特点如下:
1. 灾难恢复及高可用性:物理Standby提供了一个健全,高效的灾难恢复,以及高可用性的解决方案.更加易于管理switchover/failover角色转换及在更短的计划内或计划外停机时间;
2. 数据保护:使用物理Standby数据库,DG能够确保即使面对无法预料的灾害也能够不丢失数据.前面也提到物理Standby是基于块对块的复制,因此与对象,语句无关,Primary数据库上有什么,物理Standby数据库端也会有什么;
3. 分担Primary数据库压力:通过将一些备份任务,仅查询的需求转移到物理Standby数据库,可以有效节省Primary数据库的CPU及I/O资源;
4. 提升性能:物理Standby所使用的REDO应用技术使用最底层的恢复机制,这种机制能够绕过SQL级代码层,因此效率最高;
2. 逻辑Standby
1. 逻辑Standby也要通过Primary数据库(或其备份,或其复制库,如物理Standby)创建,因此在创建之初与物理Standby数据库类似.不过由于逻辑Standby通过SQL应用的方式应用REDO数据, 因此逻辑Standby的物理文件结构,甚至数据的逻辑结构都可以与Primary不一致;
2. 与物理Standby不同,逻辑Standby正常情况下是以READ WRITE模式打开,用户可以在任何时候访问逻辑Standby数据库,就是说逻辑 Standby是在OPEN状态执行SQL应用.同样有利也有弊,由于SQL应用自身特点,逻辑Standby对于某些数据类型及一些DDL/DML语句会有操作上的限制.可以在视图DBA_LOGSTDBY_UNSUPPORTED中查看不支持的数据类型,如果使用了这种数据类型,则不能保证数据库完全一致;
3. 除了上述物理Standby中提到的类似灾难恢复,高可用性及数据保护等特点之外,逻辑Standby还有下列一些特点:
1. 有效地利用备机的硬件资源:除灾难恢复外,逻辑Standby数据库还可用于其他业务需求.如通过在Standby数据库创建额外的索引,物化视图等提高查询性能并满足特定业务需要;又如创建新的SCHEMA(该SCHEMA在Primary数据库端并不存在),然后在这些SCHEMA中执行那些不适于在Primary数据库端执行的DDL或者DML操作等;
2. 分担Primary数据库压力:逻辑Standby数据库可以在保持与Primary同步时仍然置于打开状态,这使得逻辑Standby数据库能够同时用于数据保护和报表操作,从而将主数据库从报表和查询任务中解脱出来,节约宝贵的CPU和I/O资源;
3. 平滑升级:可以通过逻辑Standby来实现如跨版本升级,为数据库打补丁等操作.应该说应用的空间很大,而带来的风险却很小(前提是如果你拥有足够的技术实力.另外虽然物理Standby也能够实现一些升级操作,但如果跨平台的话恐怕就力不从心了,所以此项没有作为物理Standby的特点列出),我个人认为这是一种值得可行的在线的滚动的平滑的升级方式,如果你的应用支持创建逻辑Standby的话;
9. Log应用服务(Log Apply Services)
1. Data Guard通过应用REDO维持Primary数据库与各Standby数据库之间的一致性,在后台默默无闻地支撑着的就是传说中的Log应用服务.Log应用服务又分以下两种方式:
1. REDO应用:物理Standby数据库专用,通过介质恢复的方式保持与Primary数据库的同步;
2. SQL应用:逻辑Standby数据库专用,核心是通过LogMiner分析出SQL语句在Standby端执行;
3. 因此物理Standby在应用REDO数据时必须是MOUNT状态,而逻辑Standby则是以READ WRITE模式打开并应用REDO数据,不过被维护的对象默认处于只读状态,无法在逻辑Standby端直接修改;
2. Log应用服务配置选项:
1. 默认情况下,Log应用服务会等待单个归档文件全部接收之后再启动应用,如果Standby数据库配置了Standby Redologs,就可以打开实时应用(Real-Time Apply),这样Data Guard就不需要再等待接收完归档文件,只要RFS进程将REDO数据写入Standby Redologs,即可通过MRP/LSP实时写向Standby数据库;
2. REDO数据实时应用:
1. 启动实时应用的优势在于,REDO数据不需要等待归档完成,接收到即可被应用,这样执行角色切换时,操作能够执行得更快,因为日志是被即时应用的;
2. 要启动实时应用也简单,前提 Standby数据库端配置了Standby Redologs;
3. 物理Standby要启用实时应用,要在启动REDO应用的语句后附加USING CURRENT LOGFIE子句,例如:SQL>ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE;
4. 逻辑Standby要启用实时应用,只需要在启动REDO应用的语句后附加IMMEDIATE子句即可,例如:SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
3. REDO数据延迟应用:
1. 有实时就有延迟,某些情况下你可能不希望Standby数据库与Primary太过同步,那就可以在Primary数据库端发送REDO数据的相应LOG_ARCHIVE_DEST_n参数中指定DELAY属性(单位为分钟,如果指定了DELAY属性,但没有指定值,则默认是30分钟).(注意:该属性并不是说延迟发送REDO数据到Standby,而是指明归档到Standby后,开始应用的时间;)
2. 例如:设置LOG_ARCHIVE_DEST_3的DELAY属性为15分钟:SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_3=’SERVICE= ARCH VALID_FOR=(ONLINE_LOGFILES, PRIMARY_ROLE) DB_UNIQUE_NAME=Dave DELAY=15′;
3. 如果DBA在启动REDO应用时指定了实时应用,那么即使在LOG_ ARCHIVE_DEST_n参数中指定了DELAY属性,Standby数据库也会忽略DELAY属性;
4. 另外,Standby端还可以在启动REDO应用时,通过附加 NODELAY子句的方式,取消延迟应用;
5. 物理Standby可以通过下列语句取消延迟应用:SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE NODELAY;
6. 逻辑Standby可以通过下列语句取消延迟应用:SQL> ALTER DATABASE START LOGICAL STANDBY APPLY NODELAY;
4. 一般设置延迟应用的需求都是基于容错方面的考虑,如Primary数据库端由于误操作,数据被意外修改或删除,只要Standby数据库尚未应用这些修改,你就可以快速从Standby数据库中恢复这部分数据.不过自Oracle从9i版本开始提供FLASHBACK特性之后,对于误操作使用FLASHBACK特性进行恢复,显然更加方便快捷,因此DELAY方式延迟应用已经非常少见了;
3. 应用REDO数据到Standby数据库:
1. 物理Standby应用REDO数据:
1. 物理Standby启动REDO应用,数据库要处于MOUNT状态;
2. 前台应用:SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE;语句执行完成后,不会将控制权返回到命令行窗口,除非你手动中止应用.在这种情况下如果还需要对数据库进行操作,只能新开一个命令行连接,在Oracle 8i刚推出Standby特性时(那时不叫Data Guard),只提供了这种方式;
3. 后台应用:SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;这是现在比较通用的方式,语句执行完后,控制权自动返回到当前的命令行模式,REDO应用以后台进程运行.
4. 启动实时应用:附加USING CURRENT LOGFILE子句即可:SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE;
5. 如果要停止REDO应用:执行下列语句即可:SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
2. 逻辑Standby应用REDO数据:
1. SQL应用的原理是将接收到的REDO数据转换成SQL语句在逻辑Standby数据库端执行,因此逻辑Standby需要启动至OPEN状态;
2. 启动SQL应用:逻辑Standby数据库启动SQL应用没有前/后台运行之说,语句执行完之后,控制权就会自动返回当前命令行窗口;
3. 要启动SQL应用:直接执行下列语句即可:SQL> ALTER DATABASE START LOGICAL STANDBY APPLY;
4. 如果要启动实时应用:附加IMMEDIATE子句即可,例如:SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
5. 停止SQL应用:如SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
6. 由于是执行SQL语句的方式应用REDO数据,因此上述语句的执行需要等待当前执行的SQL触发的事务结束,才能真正停止REDO应用的状态;
7. 如果不考虑事务执行情况,马上停止REDO应用,可以通过下列的语句来完成:SQL> ALTER DATABASE ABORT LOGICAL STANDBY APPLY;

同一台机器上配置DataGuard

同一台机器上配置DataGuard
1. 实验环境:
1. ip:192.168.10.11;
2. hostname:primary.snda.com;
2. 设置~/.bash_profile,$ORACLE_HOME/network/admin/listener.ora和$ORACLE_HOME/network/admin/tnsnames.ora文件;
3. 创建必要的目录;
4. 修改主库的系统参数,然后关闭数据库,启动到mount状态,并修改数据库为归档模式;
5. 在主库使用spfile创建pfile:CREATE PFILE FROM SPFILE;
6. 备份主库的数据文件和控制文件;
7. 拷贝主库的文件到备库;
8. 修改备库的参数文件;
9. 设置备库的ORACLE_SID,并启动备库到nomount状态;
10. 设置备库的ORACLE_SID, 使用rman恢复备库;
11. 主库备库分别添加Standby Redo Log Fiels;
12. 重启备库,并使用spfile启动到mount状态,并设置应用日志文件;
13. 修改数据库问高可用模式;
14. 切换主库备库的角色;

— ~/.bash_profile文件内容;
ORACLE_SID=PROD
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1
PATH=/usr/sbin:$PATH
PATH=$ORACLE_HOME/bin:$PATH
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
export ORACLE_BASE ORACLE_HOME ORACLE_SID PATH LD_LIBRARY_PATH CLASSPATH
alias sqlplus=’rlwrap sqlplus’
alias rman=’rlwrap rman’
alias dgmgrl=’rlwrap dgmgrl’

— $ORACLE_HOME/network/admin/listener.ora文件内容;
LISTENER=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.snda.com)(PORT=1521))
)
)
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME=PROD)
(ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1)
)
(SID_DESC=
(SID_NAME=PRODDG)
(ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1)
)
)

— $ORACLE_HOME/network/admin/tnsnames.ora文件内容;
PROD_PRI=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.snda.com)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=PROD)
(SERVER=DEDICATED)
)
)
PROD_SBY=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.snda.com)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=PRODDG)
(SERVER=DEDICATED)
)
)

— 创建必要的目录;
mkdir -p /u01/app/oracle/oradata/PRODDG/
mkdir -p /u01/app/oracle/admin/PRODDG/adump
mkdir -p /u01/app/oracle/admin/PRODDG/bdump
mkdir -p /u01/app/oracle/admin/PRODDG/cdump
mkdir -p /u01/app/oracle/admin/PRODDG/udump
mkdir -p /u01/app/oracle/archivelog/prod
mkdir -p /u01/app/oracle/archivelog/proddg

— 修改主库的系统参数,然后关闭数据库,启动到mount状态,并修改数据库为归档模式;
ALTER SYSTEM SET DB_UNIQUE_NAME=PROD_PRI SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_CONFIG=’DG_CONFIG=(PROD_PRI,PROD_SBY)’ SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_1=’LOCATION=/u01/app/oracle/archivelog/prod VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=PROD_PRI’ SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2=’SERVICE=PROD_SBY LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=PROD_SBY’ SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_1=’ENABLE’ SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=’ENABLE’ SCOPE=SPFILE;
ALTER SYSTEM SET REMOTE_LOGIN_PASSWORDFILE=’EXCLUSIVE’ SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_FORMAT=’%t_%s_%r.arc’ SCOPE=SPFILE;
ALTER SYSTEM SET FAL_SERVER=’PROD_PRI’ SCOPE=SPFILE;
ALTER SYSTEM SET FAL_CLIENT=’PROD_SBY’ SCOPE=SPFILE;
ALTER SYSTEM SET DB_FILE_NAME_CONVERT=’/u01/app/oracle/oradata/PRODDG’,’/u01/app/oracle/oradata/PROD’ SCOPE=SPFILE;
ALTER SYSTEM SET LOG_FILE_NAME_CONVERT=’/u01/app/oracle/oradata/PRODDG’,’/u01/app/oracle/oradata/PROD’ SCOPE=SPFILE;
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=’AUTO’ SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
SHUTDOWN MOUNT;
ALTER DATABASE FORCE LOGGING;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
CREATE PFILE FROM SPFILE;

— 备份主库的数据文件和控制文件;
rman target /
BACKUP DATABASE FORMAT ‘/u01/app/oracle/flash_recovery_area/%U’;
BACKUP CURRENT CONTROLFILE FOR STANDBY FORMAT ‘/u01/app/oracle/flash_recovery_area/%U’;

— 拷贝主库的文件到备库;
cd $ORACLE_HOME/dbs
cp initPROD.ora initPRODDG.ora
orapwd file=orapwPRODDG password=oracle force=y

— 修改备库的参数文件
*.db_name=’PROD’
*.db_block_size=8192
*.db_unique_name=’PROD_SBY’
*.fal_client=’PROD_PRI’
*.fal_server=’PROD_SBY’
*.log_archive_config=’DG_CONFIG=(PROD_PRI,PROD_SBY)’
*.log_archive_dest_1=’LOCATION=/u01/app/oracle/archivelog/proddg VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=PROD_SBY’
*.log_archive_dest_2=’SERVICE=PROD_PRI LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=PROD_PRI’
*.log_archive_dest_state_1=’ENABLE’
*.log_archive_dest_state_2=’ENABLE’
*.log_archive_format=’%t_%s_%r.arc’
*.sga_target=300M
*.pga_aggregate_target=150M
*.processes=150
*.compatible=’10.2.0′
*.remote_login_passwordfile=’EXCLUSIVE’
*.standby_file_management=’AUTO’
*.undo_management=’AUTO’
*.undo_tablespace=’UNDOTBS’
*.db_file_name_convert=’/u01/app/oracle/oradata/PROD’,’/u01/app/oracle/oradata/PRODDG’
*.log_file_name_convert=’u01/app/oracle/oradata/PROD’,’/u01/app/oracle/oradata/PRODDG’
*.control_files=’/u01/app/oracle/oradata/PRODDG/control01.ctl’,’/u01/app/oracle/oradata/PRODDG/control02.ctl’

— 设置备库的ORACLE_SID,并启动备库到nomount状态;
ORACLE_SID=PRODDG
sqlplus / as sysdba
STARTUP NOMOUNT

— 设置备库的ORACLE_SID,使用rman恢复备库;
ORACLE_SID=PRODDG
rman target sys/oracle@prod_pri auxiliary /
DUPLICATE TARGET DATABASE FOR STANDBY;

— 分别在主库和备库添加Standby Redo Log files;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 (‘/u01/app/oracle/oradata/PROD/redo04.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 (‘/u01/app/oracle/oradata/PROD/redo05.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 (‘/u01/app/oracle/oradata/PROD/redo06.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 (‘/u01/app/oracle/oradata/PROD/redo07.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 (‘/u01/app/oracle/oradata/PRODDG/redo04.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 (‘/u01/app/oracle/oradata/PRODDG/redo05.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 (‘/u01/app/oracle/oradata/PRODDG/redo06.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 (‘/u01/app/oracle/oradata/PRODDG/redo07.log’) SIZE 100M;

— 重启备库,并使用spfile启动到mount状态,并设置应用日志文件;
shutdown immediate
CREATE SPFILE FROM PFILE;
startup mount
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT SESSION;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

— 修改数据库问高可用模式,在主库运行;
ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE AVAILABILITY;
ALTER SYSTEM SWITCH LOGFILE;

— 切换主库备库的角色;
1.在主库运行;
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY;
shutdown immediate;
startup mount;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
2.在备库运行;
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
ALTER DATABASE OPEN;
ALTER SYSTEM SWITCH LOGFILE;

SELECT PROTECTION_MODE, PROTECTION_LEVEL, DATABASE_ROLE, SWITCHOVER_STATUS FROM v$database;

DataGuard管理操作命令

1.相关进程:
1.RFS(Remote File Server Process):接收由Primary数据库的lgwr或arch通过Oracle Net传来的redo数据,写入standby redo logs或standby archived redo logs;
2.MRP(Managed Recovery Process):管理恢复进程;
3.FAL(Fetch Archive Log):在Primary和Standby数据库的两端同时配置;Primary端是fetch archive log server,standby端是fetch archive log client,FAL是自动探测Primary/Standby数据库之间archived logs是否有有间隔的一个进程;
2.主备库切换:
1.主库切到备库(SWITCHOVER):
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
STARTUP NOMOUNT;
ALTER DATABASE MOUNT STANDBY DATABASE;
SELECT name, open_mode, protection_mode, database_role, switchover_status from v$DATABASE;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
2.备库切到主库(SWITCHOVER):
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
STARTUP
SELECT name, open_mode, protection_mode, database_role, switchover_status from v$DATABASE;
3.FAILOVER切换:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
ALTER DATABASE OPEN;
SELECT name, open_mode, protection_mode, database_role, switchover_status from v$DATABASE;
3.切换数据库模式:
STARTUP IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE/AVAILABILITY/PROTECTION;
ALTER DATABASE OPEN;
4.测试Primary的归档能否应用到Standby:
1.查看v$archive_gap:SELECT * FROM v$archive_gap;
2.ARCHIVE LOG LIST;
5.管理操作:
1.停止Standby:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;STARTUP IMMEDIATE;
2.切换到只读模式:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;ALTER DATABASE OPEN READ ONLY;
3.切换到管理恢复模式:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE [PARALLEL 8] [USING CURRENT LOGFILE] DISCONNECT FROM SESSION;
4.查询备机归档日志应用情况:SELECT sequence#, applied FROM v$archived_log;
5.在主库上归档当前日志:ALTER SYSTEM ARCHIVE LOG CURRENT;
6.设置归档频率,强制Primary一分种归档一次:ALTER SYSTEM SET ARCHIVE_LAG_TARGET=60 SCOPE=BOTH;
6.注意事项:
1.如果在主库执行ALTER DATABASE CLEAR UNARCHIVED LOGFILE或ALTER DATABASE OPEN RESETLOGS,则DataGuard要重建;
2.出现归档日志gap时,需要找出相应的归档日志,然后将这些归档日志copy到备用节点的standby_archive_dest和log_archive_dest目录下面;需要注意的是log_archive_dest目录下也需要copy,然后ALTER DATABASE RECOVER AUTOMATIC STANDBY DATABASE;
3.新建表/表空间/datafile都能通过日志应用到备库,但新建一个临时表空间/rename datafile均不能应用到备库上;
4.应当实时察看standby库的alert文件,就能清晰明了地知道主备更新的情况,这也是排错的重要方法;
7.相关视图:
DBA_LOGSTDBY_EVENTS (Logical Standby Databases Only)
DBA_LOGSTDBY_LOG (Logical Standby Databases Only)
DBA_LOGSTDBY_NOT_UNIQUE (Logical Standby Databases Only)
DBA_LOGSTDBY_PARAMETERS (Logical Standby Databases Only)
DBA_LOGSTDBY_PROGRESS (Logical Standby Databases Only)
DBA_LOGSTDBY_SKIP (Logical Standby Databases Only)
DBA_LOGSTDBY_SKIP_TRANSACTION (Logical Standby Databases Only)
DBA_LOGSTDBY_UNSUPPORTED (Logical Standby Databases Only)
V$ARCHIVE_DEST
V$ARCHIVE_DEST_STATUS
V$ARCHIVE_GAP
V$ARCHIVED_LOG
V$DATABASE
V$DATAFILE
V$DATAGUARD_STATUS
V$LOG
V$LOGFILE
V$LOG_HISTORY
V$LOGSTDBY (Logical Standby Databases Only)
V$LOGSTDBY_STATS (Logical Standby Databases Only)
V$MANAGED_STANDBY (Physical Standby Databases Only)
V$STANDBY_LOG

使用RMAN和Broker快速搭建DataGuard环境

使用RMAN和Broker快速搭建DataGuard环境
1. 不适合在生成环境中使用,如果生成环境中搭建dg的话推荐手动配置;
2. 实验环境:
1. 主库:
1. ip:192.168.10.11;
2. hostname:primary.snda.com;
2. 备库:
1. ip:192.168.10.12;
2. hostname:standby.snda.com;
3. 分别设置主库和备库的~/.bash_profile,$ORACLE_HOME/network/admin/listener.ora和$ORACLE_HOME/network/admin/tnsnames.ora文件;
4. 修改主库的系统参数,然后关闭数据库,启动到mount状态,并修改数据库为归档模式,并创建pfile;
5. 备份主库的数据文件和控制文件;
6. 拷贝主库的文件到备库;
7. 修改备库的pfile,创建spfile,并启动到nomount状态;
8. 使用rman恢复备库;
9. 主库备库分别添加Standby Redo Log Fiels;
10. 分别修改主库和备库的初始化参数:dg_broker_start;
11. 在任意一台机器上启动dgmgrl,并配置当前的broker环境;
12. 修改数据库为高可用模式;
13. SWITCHOVER和FAILOVER操作;
14. 切换数据库的状态为只读模式和在线接收日志状态;

— 主库和备库的~/.bash_profile文件内容;
ORACLE_SID=PROD
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1
PATH=/usr/sbin:$PATH
PATH=$ORACLE_HOME/bin:$PATH
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
export ORACLE_BASE ORACLE_HOME ORACLE_SID PATH LD_LIBRARY_PATH CLASSPATH

alias sqlplus=’rlwrap sqlplus’
alias rman=’rlwrap rman’
alias dgmgrl=’rlwrap dgmgrl’

— 主库的$ORACLE_HOME/network/admin/listener.ora文件内容,修改完成后运行lsnrctl start/reload重新加载监听文件;
LISTENER=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.snda.com)(PORT=1521))
)
)
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME=PROD)
(ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1)
)
(SID_DESC=
(SID_NAME=PROD)
(ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1)
(GLOBAL_DBNAME=PROD_PRI_DGMGRL)
)
)

— 备库的$ORACLE_HOME/network/admin/listener.ora文件内容,修改完成后运行lsnrctl start/reload重新加载监听文件;
LISTENER=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(HOST=standby.snda.com)(PORT=1521))
)
)
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME=PROD)
(ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1)
)
(SID_DESC=
(SID_NAME=PROD)
(ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1)
(GLOBAL_DBNAME=PROD_SBY_DGMGRL)
)
)

— 主库和备库的$ORACLE_HOME/network/admin/tnsnames.ora文件
PROD_PRI=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.snda.com)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=PROD)
(SERVER=DEDICATED)
)
)

PROD_SBY=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=standby.snda.com)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=PROD)
(SERVER=DEDICATED)
)
)

— 修改主库的系统参数,然后关闭数据库,启动到mount状态,并修改数据库为归档模式,并创建pfile;
ALTER SYSTEM SET db_unique_name=PROD_PRI scope=spfile;
ALTER SYSTEM SET db_recovery_file_dest_size=4G;
ALTER SYSTEM SET db_recovery_file_dest=’/u01/app/oracle/flash_recovery_area’;
ALTER SYSTEM SET log_archive_dest_1=’LOCATION=/u01/app/oracle/flash_recovery_area’;
ALTER SYSTEM SET log_archive_dest_2=”;
ALTER SYSTEM SET local_listener=”;
ALTER SYSTEM SET dispatchers=”;
ALTER SYSTEM SET standby_file_management=AUTO;

SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE FORCE LOGGING;
ALTER DATABASE ARCHIVELOG;
— ALTER DATABASE FLASHBACK ON;
ALTER DATABASE OPEN;
CREATE PFILE FROM SPFILE;

— 备份主库的数据文件和控制文件;
rman target /
BACKUP DATABASE FORMAT ‘/u01/app/oracle/flash_recovery_area/%U’;
BACKUP CURRENT CONTROLFILE FOR STANDBY FORMAT ‘/u01/app/oracle/flash_recovery_area/%U’;

— 拷贝主库的文件到备库;
scp /u01/app/oracle/flash_recovery_area/* oracle@standby.snda.com:/u01/app/oracle/flash_recovery_area/
scp $ORACLE_HOME/dbs/initPROD.ora oracle@standby.snda.com:$ORACLE_HOME/dbs/
scp $ORACLE_HOME/dbs/orapwPROD oracle@standby.snda.com:$ORACLE_HOME/dbs/

— 修改备库的pfile,创建spfile,并启动到nomount状态;
修改备库的参数文件,只修改db_unique_name=’PROD_SBY’即可;
CREATE SPFILE FROM PFILE;
STARTUP NOMOUNT;

— 使用rman恢复备库;
rman target sys/oracle@prod_pri auxiliary /
DUPLICATE TARGET DATABASE FOR STANDBY NOFILENAMECHECK;

— 主库备库分别添加Standby Redo Log Fiels;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 (‘/u01/app/oracle/oradata/PROD/redo04.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 (‘/u01/app/oracle/oradata/PROD/redo05.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 (‘/u01/app/oracle/oradata/PROD/redo06.log’) SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 (‘/u01/app/oracle/oradata/PROD/redo07.log’) SIZE 100M;

— 分别修改主库备库的初始化参数;
ALTER SYSTEM SET dg_broker_start=TRUE;

— 在任意一台机器上启动dgmgrl,并配置当前的broker环境;
dgmgrl sys/oracle@prod_pri
CREATE CONFIGURATION DGCONFIG1 AS PRIMARY DATABASE IS PROD_PRI CONNECT IDENTIFIER IS PROD_PRI;
ADD DATABASE PROD_SBY AS CONNECT IDENTIFIER IS PROD_SBY MAINTAINED AS PHYSICAL;
ENABLE CONFIGURATION;
SHOW CONFIGURATION;

— 修改数据库为高可用的保护状态;
EDIT DATABASE PROD_PRI SET PROPERTY LogXptMode=’Sync’;
EDIT DATABASE PROD_SBY SET PROPERTY LogXptMode=’Sync’;
EDIT CONFIGURATION SET PROTECTION MODE AS MaxAvailability;

— 切换数据库的主备角色;
SWITCHOVER TO PROD_SBY;
SWITCHOVER TO PRDO_PRI;
SELECT PROTECTION_MODE, PROTECTION_LEVEL, DATABASE_ROLE, SWITCHOVER_STATUS FROM v$database;

— FAILOVER操作;
FAILOVER TO PROD_PRI;
FAILOVER TO PROD_SBY;

— 切换数据库的状态为只读模式和在线接收日志状态;
EDIT DATABASE PROD_SBY SET STATE=’READ-ONLY’;
EDIT DATABASE PROD_SBY SET STATE=’ONLINE’;

— 设置数据库的其它属性;
EDIT DATABASE db SET PROPERTY StandbyFileManagement=’AUTO’;
EDIT DATABASE db SET PROPERTY StandbyArchiveLocation=’/u01/app/oracle/flash_recovery_area’;

— 删除表空间和表空间所有的内容;
DROP TABLESPACE tbs INCLUDE CONTENTS CASCADE CONTRAINTS;

GoldenGate学习7–其它问题

1.truncate操作要单独处理,在EXTRACT和REPLICAT配置文件中添加GETTRUNCATES;
2.主键的解决办法:一个生成奇数,一个生成偶数
Database-generated values
Do not replicate database-generated sequential values in a bi-directional configuration.
The range of values must be different on each system, with no chance of overlap. For
example, in a two-database environment, you can have one server generate even values,
and the other odd. For an n-server environment, start each key at a different value and
increment the values by the number of servers in the environment. This method may not
be available to all types of applications or databases. If the application permits, you can
add a location identifier to the value to enforce uniqueness.

阻止数据循环
1.阻止抽取复制的操作:
1.GETAPPLOPS|IGNOREAPPLOPS
2.GETREPLICATES|IGNOREREPLICATES
2.标识复制的事务:
TRANLOGOPTIONS EXCLUDEUSER
TRANLOGOPTIONS EXCLUDEUSERID

中间主键冲突了怎么办;
主库宕机了,剩余数据是否会同步到备机;

mgr
PURGEOLDEXTRACTS /opt/gg/trails/w1*, USECHECKPOINTS, MINKEEPFILES 10
PURGEOLDEXTRACTS /opt/gg/trails/w2*, USECHECKPOINTS, MINKEEPFILES 10
AUTORESTART ER *, RETRIES 3, WAITMINUTES 5
PURGEDDLHISTORY MINKEEPDAYS 3, MAXKEEPDAYS 5, FREQUENCYMINUTES 30
PURGEMARKERHISTORY MINKEEPDAYS 3, MAXKEEPDAYS 5, FREQUENCYMINUTES 30

init data on soruce
1.add extract eintss, soruceistable
2.edit params eintss
EXTRACT eintss
userid system, password “oracle”
rmthost xxx, mgrport 7809
rmttask replicat, group riniss
table gg.*;

init data on target
3. add replicat riniss, specialrun
info replicat *, tasks;
4.edit params riniss
replicat riniss
assumetargetdefs
userid system, password oracle
discardfile ./dirrpt/RINISS.dsc, purge
map gg.*, target gg.*;

on source
5.start extract einiss;
view report einitss;
6.view report riniss

source 2 target on source
1.ADD EXTRACT ext_s2t, TRANLOG, BEGIN NOW, THREADS 1
EXTRACT ext_s2t
USERID system, PASSWORD oracle
EXTTRAIL ./dirdat/st
DLL INCLUDE MAPPED
TABLE gg.*;

2.ADD EXTTRAIL ./dirdat/st, EXTRACT ext_s2t

3.ADD EXTRACT pump_sr, EXTTRAILSOURCE ./dirdat/st, BEGIN NOW
EXTRACT pump_sr
USERID system, PASSWORD oracle
RMTHOST 192.168.10.12, MGRPORT 7809
RMTTRAIL ./dirdat/tt
PASSTHRU

TABLE gg.*;

4.ADD RMTTRAIL ./dirdat/tt, EXTRACT pump_sr

source 2 target on target
5.ADD REPLICAT repl_tt, EXTTRAIL ./dirdat/tt, BEGIN NOW
REPLICAT repl_tt
ASSUMETARGETDEFS
DLL INCLUDE MAPPED
USERID system, PASSWORD oracle
DISCARDFILE ./dirrpt/repl_tt.dsc, PURGE
MAP gg.*, TARGET gg.*;

————————————————————-
target 2 source on target
1.ADD EXTRACT ext_t2s, TRANLOG, BEGIN NOW, THREADS 1
EXTRACT ext_t2s
USERID system, PASSWORD oracle
EXTTRAIL ./dirdat/ts
DLL INCLUDE MAPPED
TABLE gg.*;

2.ADD EXTTRAIL ./dirdat/ts, EXTRACT ext_t2s

3.ADD EXTRACT pump_tt, EXTTRAILSOURCE ./dirdat/ts, BEGIN NOW
EXTRACT pump_tt
USERID system, PASSWORD oracle
RMTHOST 192.168.10.11, MGRPORT 7809
RMTTRAIL ./dirdat/ss
PASSTHRU
TABLE gg.*;

4.ADD RMTTRAIL ./dirdat/ss, EXTRACT pump_tt

target 2 source on srouce
5.ADD REPLICAT repl_ss, EXTTRAIL ./dirdat/ss, BEGIN NOW
REPLICAT repl_ss
ASSUMETARGETDEFS
DLL INCLUDE MAPPED
USERID system, PASSWORD oracle
DISCARDFILE ./dirrpt/repl_ss.dsc, PURGE
MAP gg.*, TARGET gg.*;

冲突的现象
1.插入时主键冲突
2.更新/删除冲突

解决的办法:
1.读写分离
2.设置很小的延迟,A操作的更改在B操作的更改完成之前反应到B的话就避免了冲突;

使用gg的CDR(Conflict Detection and Resolution)特性
1.解决插入时主键冲突
2.更新/删除时找不到数据;

约束:数据库必须在同类的OS平台上,只支持可以比较而且是没有显式转换的数据类型

GoldenGate学习6–Oracle到SQLServer数据同步

1.相关环境;
Oracle:11.2.0.1 on Linux x64
SQLServer:2005 on Windows 2008R2 x64
OGG:12.1.2.1.0

2.准备源端(Oralce端);
2.1开启数据库级别附加日志;
SELECT supplemental_log_data_min, force_logging FROM v$database;
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
SQL> ALTER DATABASE FORCE LOGGING;
SELECT supplemental_log_data_min, force_logging FROM v$database;
SQL> ALTER SYSTEM SWITCH LOGFILE;
2.2创建用户并授权;
CREATE USER ggadm IDENTIFIED BY ‘********’;
EXEC dbms_goldengate_auth.grant_admin_privilege(‘ggadm’); for Oracle 11.2.0.4 and later
EXEC dbms_goldengate_auth.grant_admin_privilege(‘ggadm’,grant_select_privileges=>true); for Oracle 11.2.0.3 or Earlier
2.3开启相关参数;
ALTER SYSTEM SET ENABLE_GOLDENGATE_REPLICATION=true; for an Oracle 11.2.0.4 or greated database
2.4在ogg中配置安全认证;
./ggsci
ADD CREDENTIALSTORE
ALTER CREDENTIALSTORE ADD USER ggadm, PASSWORD ******** ALIAS alias ogg
2.5开启表级别附加日志(可选);
./ggsci
DBLOGIN USERIDALIAS ogg
ADD TRANDATA [container.]schema.table
INFO TRANDATA [container.]schema.table

3.配置表结构映射;
3.1在源端定义需要映射的表;
./ggsci
EDIT PARAM DEFGEN
DEFSFILE ./dirdef/source.def, PURGE
USERIDALIAS alias
TABLE schema.table1;
TABLE schema.table1;
3.2生成映射文件;
shell> defgen paramfile ./dirprm/defgen.prm
3.3拷贝文件到目标端相应的目录;

4.在源端和目标端分别开启管理进程;
EDIT PARAMS mgr

PORT 7809

START mgr
INFO mgr

5.在源端配置数据泵抽取(Data Pump Extract)进程;
ADD EXTRACT EXT1, TRANLOG, BEGIN NOW, THREADS 1
EDIT PARAMS ext1

EXTRACT ext1
USERIDALIAS ogg
RMTHOST dst_ip, MGRPORT 7809 ENCRYPT AES192, KEYNAME securekey2
RMTTRAIL ./dirdat/rt
# SEQUENCE schema.sequence_name;
TABLE schema.table;

ADD RMTTRAIL ./dirdat/rt, EXTRACT ext1, MEGABYTES 100;
INFO RMTTRAIL *

# START EXTRACT ext1
# INFO EXTRACT ext1, DETAIL

6.配置目标端(SQLServer端);
6.1配置ODBC数据源:控制面板->管理工具->数据源(ODBC)->系统DSN(添加),择驱动程序类型为[SQL Server Native Client],比如:名字为ogg;
6.2在目标端创建一样的表结构;
6.3添加检查点表;
./ggsci
EDIT PARAMS ./GLOBALS

CHECKPOINTTABLE ggschkpt

DBLOGIN SOURCEDB ogg, USERID uid, PASSWORD pwd
ADD CHECKPOINTTABLE
退出之后再进一次客户端;
6.4在目标端配置复制(Change Delivery)进程;
ADD REPLICAT rpl1, EXTTRAIL E:\ogg121\dirdat\rt
EDIT PARAMS rpl1

REPLICAT rpl1
TARGETDB ogg, USERID uid, PASSWORD pwd
HANDLECOLLISIONS
SOURCEDEFS E:\ogg121\dirdef\source.def
REPERROR DEFAULT, DISCARD
DISCARDFILE E:\ggate\dirrpt\rpl1.dsc APPEND
GETTRUNCATES
MAP schema.table, TARGET db.table;

# START REPLICAT rpl1
# INFO REPLICAT rpl1

7.查看对应的报告;
7.1查看抽取进程报告;
SEND EXTRACT EXT1, REPORT
VIEW REPORT EXT1
7.2查看复制进程报告;
SEND REPLICAT RPL1, REPORT
VIEW REPORT RPL1

TIPS:在Windows下安装ogg时需要注册服务;
C:\GG_DIR> INSTALL ADDSERVICE
./ggsci
CREATE SUBDIRS

GoldenGate学习5–Oracle to MySQL

GoldenGate for Oracle to MySQL
1. Environments;
1. Source Database:
1. Oracle:11g R2;
2. Ip Address:192.168.10.11;
3. Hostname:primary.snda.com;
4. Oracle SID:primary;
2. Target Database:
1. Mysql:5.5.21;
2. Ip Address:192.168.10.55;
3. Hostname:master.snda.com;
2. Oracle to Mysql configuration;
3. Prepare the Environment;
1. Description:
1. The GoldenGate software must be installed on both the source and target systems;
2. The installation includes a sample database and scripts to generate initial data as well as subsequent update operations;
3. The source and target tables are created and loaded with initial data;
4. the GoldenGate Manager processes are also started so that other processes may be configured and started;
2. Prepare the Oracle source environment:
1. 在源数据库创建gg用户,并赋予一定的权限:create user gg identified by gg default tablespace example;grant connect, resource to gg;(一定要保证表/表空间是logging的,select table_name, tablespace_name, logging, owner from dba_tables where owner=’GG’;)
2. 在源数据库的gg用户下创建测试使用的表(脚本是GoldenGate安装目录下的demo_ora_create.sql文件);
3. 在源数据库的测试表中添加测试数据(脚本是GoldenGate目录下的demo_ora_insert.sql文件);
4. Add supplemental logging;
5. Configure the Manager process on the source;
3. Prepare the Mysql target environment:
1. 准备数据;
2. Configure the Manager process;
3. create a user;
4. Configure Initial Data Load using Direct Load;
1. Initial Load Methods:
1. Oracle GoldenGate Methods;
2. Database-specific Methods:
1. Backup/Restore;
2. Export/Import;
3. SQL scripts;
4. Break mirror;
5. Transportable tablespaces;
6. Note:
1. Run a test initial load early on for timing and sizing;
2. Run the actual initial load after starting change capture on the source;
3. Current use;
2. Initial data capture on source:
1. add the initial load capture batch task group:GGSCI> add extract eint, sourceistable;(sourceistable 参数代表这是initial data);
2. configure the initial load capture parameter file:GGSCI> edit params eint
;
3. Initial data delivery on target:
1. add the initial load delivery batch task:GGSCI>add replicat rini
, specialrun;(specialrun:Create a Replicat special run as a task)
2. configure the initial load delivery parameter file;(assumetargetdefs:假定目标数据库和源数据库表结构一致;discardfile:失败的记录记录的文件;)
4. Define the source.def:
1. 定义defgen参数文件;
2. 执行定义参数文件:dengen paramfile ./dirprm/defgen.prm,会生成表结构定义文件./dirdef/source.def;
3. 拷贝到目标数据库相应的目录下;
5. Execute the initial load process:
1. start extract process:start extract eini
;
2. view the results on the target system:view report rini
;
3. 在目标数据库中查看数据;
5. Configure Change Capture(online mode);
1. Extract can be configured to:
1. Capture changed data from database logs;
2. Capture data directly from source tables for initial data load;
3. Write the data to a local or remote trail or file;
2. add the extract group:add extract emsq
, tranlog, begin now, threads ;
3. create the extract parameter file;
4. define the GoldenGate trail:add rmttrail ./dirdat/, extract emsq, megabytes 5;(default 10M size)
5. start the capture process:start extract eora
;
6. 可以通过view report eorasd查看日志;
6. Configure Change Delivery;
1. set up the checkpoint table;
1. create a GLOBALS file on the target system;(exit and save)
2. activate the GLOBALS parameters;
2. Configure Change Delivery;
1. add the replicat group;
2. create replicat parameter file;
3. start the replicat process;
7. Generate Activity and Verify the Results;
1. exceute miscellaneous update, insert and delete operations on source system;
2. verify results on the source system;
3. verify results on the target system;
4. turn off error handling;
8. Parameter Files Knowlege:
1. Editing Parameter Files:
1. Edit parameter files to configure GoldenGate processes;
2. The GLOBALS parameter file is identified by its file path:GGSCI>edit params ./GLOBALS;
3. Manager and utility parameter files are identified by keywords:GGSCI>edit params mgr/defgen;
4. Extract and Replicat parameter files are identified by the process groiup name:GGSCI>edit params ;
2. GLOBALS Versus Process Parameters:
1. GLOBALS parameter apply to all processes:
1. set when Manager starts;
2. reside in /GOLBALS;
2. Process parameters apply to a specific process(Manager, Extract, Server Collector, Replicat, Utilities):
1. set when the process starts;
2. override GOLBALS settings;
3. reside by defaults in the dirprm directory in files named .prm;
4. most apply to all tables processed but some can be specified at the table level;
3.
GLOBALS Parameters:
1. Control things common to all processes in a GoldenGate instance;
2. Can be overridden by parameters at the process level;
3. Must be created before any processes are started;
4. Must exit GGSCI to save;
5. Once set, rarely changed;
6. MGRSERVNAME:defines a unique Manager service name;
7. CHECKPOINTTABLE:Defines the table name used for Replicat’s checkpoint table;

GoldenGate学习4–Oracle to Oracle workshop demonstration

GoldenGate for Oracle to Oracle
1. Environments;
1. Source Database:
1. Oracle:11g R2;
2. Ip Address:192.168.10.11;
3. Hostname:ggsource.snda.com;
4. Oracle SID:ggsource;
2. Target Database:
1. Oracle:11g R2;
2. Ip Address:192.168.10.12;
3. Hostname:ggtarget.snda.com;
4. Oracle SID:ggtarget.snda.com;
2. Oracle to Oracle configuration;
3. Prepare the Environment;
1. Description:
1. The GoldenGate software must be installed on both the source and target systems;
2. The installation includes a sample database and scripts to generate initial data as well as subsequent update operations;
3. The source and target tables are created and loaded with initial data;
4. the GoldenGate Manager processes are also started so that other processes may be configured and started;
2. 准备测试数据:
1. 分别在源数据库和目标数据库创建gg用户,并赋予一定的权限:create user gg identified by gg default tablespace example;grant connect, resource to gg;(一定要保证表是logging的,select table_name, tablespace_name, logging, owner from dba_tables where owner=’GG’;)
2. 分别在源数据库和目标数据库的gg用户下创建测试使用的表(脚本是GoldenGate安装目录下的demo_ora_create.sql文件);
3. 只在源数据库的测试表中添加测试数据(脚本是GoldenGate目录下的demo_ora_insert.sql文件);
3. Configure the Manager process on the source and target:
1. Create the Manager parameter file;
2. Use edit to assign a port(7809 default),其实是编辑了/gg11/dirprm/mgr.prm文件;
3. Start the Manager and View the Manager process;
4. 查看后台进程验证:ps -ef | grep mgr;
5. 可以通过直接打开日志文件(/gg11/dirrpt/MGR.rpt文件)或者使用view report mgr命令查看Manager的日志;
4. Supplemental Logging:
1. Add database level supplmental logging on source and target:done when GoldenGate installed;
2. Add table level supplemental logging on srouce and target;
3. Verify that supplemental logging infos;
4. Configure Initial Data Load;
1. Initial Load Methods:
1. Oracle GoldenGate Methods;
2. Database-specific Methods:
1. Backup/Restore;
2. Export/Import;
3. SQL scripts;
4. Break mirror;
5. Transportable tablespaces;
6. Note:
1. Run a test initial load early on for timing and sizing;
2. Run the actual initial load after starting change capture on the source;
3. Current use;
2. Initial data capture:
1. add the initial load capture batch task group:GGSCI> add extract eint, sourceistable;(sourceistable 参数代表这是initial data);
2. configure the initial load capture parameter file:GGSCI> edit params eint
;
3. Initial data delivery:
1. add the initial load delivery batch task:GGSCI>add replicat rini
, specialrun;(specialrun:Create a Replicat special run as a task)
2. configure the initial load delivery parameter file;(assumetargetdefs:假定目标数据库和源数据库表结构一致;discardfile:失败的记录记录的文件;)
4. Execute the initial load process:
1. start extract process:start extract eint
;
2. view the results on the target system:view report rini
;
3. 在目标数据库中查看数据;
5. Configure Change Capture(online mode);
1. Extract can be configured to:
1. Capture changed data from database logs;
2. Capture data directly from source tables for initial data load;
3. Write the data to a local or remote trail or file;
2. add the extract group:add extract eora
, tranlog, begin now, threads ;
3. create the extract parameter file;
4. define the GoldenGate trail:add rmttrail ./dirdat/, extract eora, megabytes 5;(default 10M size)
5. start the capture process:start extract eora
;
6. 可以通过view report eorasd查看日志;
6. Configure Change Delivery;
1. set up the checkpoint table;
1. create a GLOBALS file on the target system;(exit and save)
2. activate the GLOBALS parameters;
2. Configure Change Delivery;
1. add the replicat group;
2. create replicat parameter file;
3. start the replicat process;
7. Generate Activity and Verify the Results;
1. exceute miscellaneous update, insert and delete operations on source system;
2. verify results on the source system;
3. verify results on the target system;
4. turn off error handling;
8. Parameter Files Knowlege:
1. Editing Parameter Files:
1. Edit parameter files to configure GoldenGate processes;
2. The GLOBALS parameter file is identified by its file path:GGSCI>edit params ./GLOBALS;
3. Manager and utility parameter files are identified by keywords:GGSCI>edit params mgr/defgen;
4. Extract and Replicat parameter files are identified by the process groiup name:GGSCI>edit params ;
2. GLOBALS Versus Process Parameters:
1. GLOBALS parameter apply to all processes:
1. set when Manager starts;
2. reside in /GOLBALS;
2. Process parameters apply to a specific process(Manager, Extract, Server Collector, Replicat, Utilities):
1. set when the process starts;
2. override GOLBALS settings;
3. reside by defaults in the dirprm directory in files named .prm;
4. most apply to all tables processed but some can be specified at the table level;
3.
GLOBALS Parameters:
1. Control things common to all processes in a GoldenGate instance;
2. Can be overridden by parameters at the process level;
3. Must be created before any processes are started;
4. Must exit GGSCI to save;
5. Once set, rarely changed;
6. MGRSERVNAME:defines a unique Manager service name;
7. CHECKPOINTTABLE:Defines the table name used for Replicat’s checkpoint table;

GoldenGate学习3–Install Oracle GoldenGate on Linux

Oracle GoldenGate for Linux Installation
1. Objectives
1. Download an Oracle GoldenGate Media Pack;
2. Install Oracle GoldenGate on Linux, Unix and Windows;
3. Locate and use Oracle GoldenGate documentation;
4. Use the Oracle GoldenGate command interface;
2. Installation Steps:
1. Downloading Oracle GoldenGate software;
1. GoldenGate是属于Oracle的中间件,可以到www.oracle.com->Downloads菜单->Middleware下选择GoldenGate及帮助文档下载(http://www.oracle.com/technetwork/middleware/goldengate/downloads/index.html);
2. 也可以到http://edelivery.oracle.com登陆后下载;
3. 选择Media Pack:Oracle Fusion Middleware and Platform:Linux x86;
4. 选择GoldenGate软件,并选择合适的版本;
5. 如果是其他数据库(mysql,mssql,db2),应该选择;
2. Preparing the Oracle GoldenGate software;
1. 把下载的文件上传到服务器,然后解压缩:unzip ogg112101_fbo_ggs_Linux_x86_ora11g_32bit.zip;
2. 创建GoldenGate的目录/gg11,然后把tar包解到/gg11目录下:tar xvf /tools/fbo_ggs_Linux_x86_ora11g_32bit.tar -C /gg11/;
3. 为了避免权限的问题,把/gg11目录修改为oracle:oinstall用户和组,oracle用户安装oracle软件也安装GoldenGate软件:chown -R oracle:oinstall /gg11/;
3. Setting ORACLE_HOME and ORACLE_SID:安装oracle时已经设置;
4. Setting library paths for dynamic builds;
5. Installing the Oracle GoldenGate software;
1. 进入到GoldenGate软件的目录/gg11/并执行ggsci命令;
2. 执行CREATE SUBDIRS命令安装;
3. 安装完成,查看生成的目录:ll -ltr /gg11/;
6. Oracle-specific installation steps;
1. View the supplemental logging at the database level;
2. Turn on supplemental logging at the database level(把一些附加信息添加到redo log中,默认redo log只记录rowid,因为两台机器的rowid是不同的,所以要添加附加信息);
3. Switch to the next redo log file;
3. Introduce GoldenGate Directories
1. dirchk:GoldenGate checkpoint files;
2. dirdat:GoldenGate trail and extract files;
3. dirdef:Data definitions produced by DEFGEN and used to translate heterogeneous data;
4. dirpcs:Process status files;
5. dirprm:Parameter files;
6. dirrpt:Process report files;
7. dirsql:SQL scripts;
8. dirtmp:Temporary storage for transactions that exceed allocated memory;
4. Oracle GoldenGate Important Documentation;
1. Administration Guide;
2. Reference Guide;
3. Troubleshooting and Tuning Guide;
5. Command Interface-Starting and Help,命令行下如何使用帮助;
1. 进入GoldenGate目录,运行ggsci命令,此时目录下的help.txt文件才会被加载进来,使用help 或者help all命令;
2. 查看具体某条命令的帮助使用:help 命令;
3. 查看历史命令:history;
4. 执行历史命令:!n;
5. 查看进程的信息:info process;查看所有进程的信息:info all;
6. 查看gg应用日志:view ggsevt;
7. 退出:quit or exit;
6. Warnings & Errors:
1. 在安装Oracle的环境安装GoldenGate的时候,如果报找不到libnnz11.so动态链接库的话,是LD_LIBRARY_PATH环境变量没有设置正确;
2. 在安装Mysql的环境安装GoldenGate的时候,是会报找不到libnnz11.so和libclntsh.so.11.1两个动态链接库的,首先在LD_LIBRARY_PATH环境变量中添加gg的安装目录的路径,然后把Oracle环境中这两个动态链接库拷贝到gg的安装目录即可;(纠结了半天,发现是gg的版本下错了,有专门对mysql的版本,应该不会出现这样的错误,orz…..)

GoldenGate学习2–Oracle GoldenGate technical architecture

Oracle GoldenGate Technical Architecture
1. Objectives:
1. Describe Oracle GoldenGate uses;
2. Lean the components of Oracle GoldenGate;
3. Explain change capture and delivery(with and without a dump);
4. Explain inital data load;
5. Contrast batch and online operation;
6. Explain Oracle GoldenGate checkpointing;
7. Describe Oracle GoldenGate parameters, process groups and GGSCI commands;
2. Oracle GoldenGate Users:
1. Primarily userd for change data capture and delivery from database transaction logs;
2. Can optionally be used for initial load directly from database tables:
1. Especially usefull for synchronizing heterogeneous databases,对异构数据库之间同步数据特别有用;
2. Database-specific methods may be preferable for homogeneous configurations,同构数据库之间最好使用数据库本身的方法;
3. Oracle GlodenGate Components:
1. Extract:process,source;
2. Data Pump:process,source;
3. Replicat:process,target;
4. Trails or Extract files:file,source and target;
5. Checkpoints:process;
6. Manager:process,source and target;
7. Collector:process,target;
4. 使用中的各种场景:
1. Change Data Capture and Delivery;
2. Change Data Capture and Delivery using a Data Pump;
3. Bidirectional Configuration;
4. Initial Load;
5. Abount the trails:
1. To support the continuous extraction and replication of database changes, Oracle GoldenGate stores the captured changes temporarily on disk in a series of files called a trail;
2. A trail can exist on the source or target system, or an intermediary system, depending on your configuration;
3. On the local system it’s know as an extract trail(or local trail), On a remote system it’s known as a remote trail;
4. All files names in a trail begin with the same two characters which you assign when you create the trail(max 10m default). As files are created, each name is appended with a unique, six-digit serial number from 000000 through 999999, for example:/gg11/dirdat/tr000018;
6. Data Pump:In most business cases, you should use a data pump, some reasons for using a data pump include the followint;
1. Protection against network and target failures;
2. Implementing serveral phases of data filtering or transformation;
3. Consolidating data from many sources to a central target;
4. Synchronizing one source with multiple targets;
7. Procesing Methods:
1. Oracle GoldenGate can be configured for the following purposes:
1. A static extraction of selected data records from one database and loading of those records to another database;
2. Online or batch extraction and replication of selected transactional data changes and DDL changes(for supported database) to keep source and target data consistent;
3. Extraction from database and replication to a file outside the database;
2. Methods:
1. An online process runs until stopped by a user, you can use online processes to continuously extract and replicate transactional changes and DDL changes(where supported);
2. A bach run, or special run, process extracts or replicates database changes that were generated within know begin and end points;
3. A task is a special type of batch run process and is used for certain initial load methods. A task is a configuration in which Extract communicates directly with Replicat over TCP/OP. Neither a Collector process nor temporary disk storage in a trail or file is used;
8. Checkpointing:Capture, Pump, and Delivery save positions to a checkpoint file so they can recover in case of failure;
9. Parameters, Process Groups and Commands:
1. GoldenGate processes are configured by ASCII parameter files;
2. A process group consists of:
1. An Extract or Replicat process;
2. Associated parameter file;
3. Associated checkpoint file;
4. Any other files associated with that process;
5. Each process group on a system must have a unique group name;
3. Processes are added and started using the GoldenGate Software Command Interface(GGSCI) with the group name;
4. GGSCI commands also add trails, check process status,etc;

GoldenGate学习1–Oracle GoldenGate Overview

Oracle GoldenGate Overview
1. Oracle GoldenGate software enable real-time, continuous movement of transactional data across operational and analytical business systems;
2. Real-Time Acccess to Real-Time Information
1. Real-Time Access:availability,the degree to which information can be instantly accessed;
2. Real-Time Information:integration,the process of combining data from different sources to provide a unified view;
3. Transactional Data Management
1. Oracle GoldenGate provides low-impact capture, routing, transformation, and delivery of database transactions across heterogeneous environments in real time;
2. Key Capabilities:
1. Real Time:moves with sub-second latency;
2. Heterogeneous:moves changed data across different databases and platforms;
3. Transactional:maintains transaction integrity;
3. Additoinal Differentiators:
1. Performance:log-based capture moves thousands of transactions per second with low impact;
2. Extensibility and Flexibility:meets variety of customer needs and data environments with open, modular architecture;
3. Relibility:resilient against interrputions and failures;
4. Technical Architecture Overview;
5. Oracle GoldenGate Topologies;
6. Oracle GoldenGate Solutions:
1. High Availability and Disaster Torlerance:
1. Live Standby;
2. Active-Active;
3. Zero-Downtime Operations for upgrades, migrations, Maintenance;
2. Real-Time Data Integration:
1. Real-time Data warehousing;
2. Live Reporting;
3. Transactional Data Integration;
3. Oracle GoldenGate Solutions Overview;
7. Oracle GoldenGate:Databases and Platforms
1. O/S and Platforms:
1. Windows 2000, 2003, xp;
2. Linux;
3. Sun Solaris;
4. HP NonStop;
5. HP-UX;
6. HP TRU64;
7. HP OpenVMS;
8. IBM AIX;
9. IBM z/OS;
2. Databases:
1. Capture:
1. Oracle;
2. Mysql;
3. IBM DB2;
4. MSSQL;
5. Sybase ASE;
6. Ingres;
7. Teradata;
8. Enscribe;
9. SQL/MP;
10. SQL/MX;
2. Delivery:
1. all listed above;
2. HP Neoview, Netezza and any ODBC compatible databases;
3. ETL products;
4. JMS message queues or topics;
8. Oracle GoldenGate and Oracle Active Data Guard;
1. For information distribution and consolidation, application upgrades and changes:use goldengate-heterogeneous,active-active,transformations,subsetting;
2. for disaster recovery/data protection/ha:
1. simple full oracle database protection:use active data guard;
2. applicatoin desiring flexible ha,active-active,schema change,platform changes:use oracle goldengate;
3. combine the two for full database protection and information distribution;
9. Oracle GoldenGate Advantages;
10. Oracle GoldenGate Director(gg的图形化管理界面)
1. Manages,defines,configures,and reports on Oracle GoldenGate components;
2. Key features:
1. Centralized management of Oracle GoldenGate modules;
2. Rich-client and Web-based inferfaces;
3. Alert notifications and integration with 3rd-party monitoring products;
4. Real-time feedback;
5. Zero-impact implementation;
3. A graphical enterprise application that offers a visual and intuitive way to define,configure,manage,and report on all GoldenGate transactional data synchronization processes;
4. Prerequisites:
1. oracle weblogic server 11g standard,includes a JDBC driver needed for the Diector repository and appropriate version of JRE;
2. the Director Server repository requires databses:oracle or mysql 5.x;
3. Director installer requires a windows system and Unix or Linux systems;
11. Oracle GoldenGate Veridata(数据比较工具);
1. A high-speed,low impact data comparison solution:
1. identifies and reports data discrepancies between two database without interrupting those systems or the business processes they support;
2. supports Oracle, Teradata, MSSQL, NonStop, SQL/MP and Enscribe;
3. Support homogeneous and heterogeneous compares;
2. Benefits:
1. Reduce financial/legal risk exposure;
2. Speed and simplify IT work in comparing data sources;
3. No disruption to business systems;
4. Imporved failover to backup systems;
5. Confident decision-making and reporting;
12. Oracle GoldenGate products
1. Oracle GoldenGate:Includes GoldenGate Capture,Deliver and Active Data Guard and XSystem;
2. Oracle GoldenGate for Mainframe:Includes GoldenGate Capture and Deliver for HP NonStop and IMB DB2 on z/OS;
3. Oracle GoldenGate Veridata:Add-on capability to validate data in replicated systems;
4. Management Pack for GoldenGate:Add-on management pack,includes Oracle GoldenGate Director;
5. Oracle GoldenGate Adapters:Pre-packaged application content,such as for Flat File and Java adapters;
13. GodelGate and Streams
1. GoldenGate is Oracle’s strategic replicatoin solution;
2. Streams continues to be a supported Oracle Databases feature;
3. Best Stream technology will be integrated into GoldenGate;

MySQL8新特性-Roles

一个MySQL的角色是一些权限的集合。就像一个帐号一样,可以对他进行权限的赋权和收回。
我们可以把角色授权给用户,这样帐号就拥用了角色的权限。我们可以同一个角色赋权给不同的帐号,也可以把不同的角色给同一个帐号。

CREATE ROLE and DROP ROLE enable roles to be created and removed.
GRANT and REVOKE enable privilege assignment and revocation for user accounts and roles.
SHOW GRANTS displays privilege and role assignments for user accounts and roles.
SET DEFAULT ROLE specifies which account roles are active by default.
SET ROLE changes the active roles within the current session.
The CURRENT_ROLE() function displays the active roles within the current session.
The mandatory_roles and activate_all_roles_on_login system variables enable defining mandatory roles and automatic activation of granted roles when users log in to the server.

创建一个角色:
CREATE ROLE ‘app_developer’;
给角色赋权:
GRANT ALL ON test.* TO ‘app_developer’;
把角色的权限赋给用户:
如果以前我们可以直接使用GRANT ALL ON test.* TO ‘dev1’@’localhost’ IDENTIFIED BY ‘dev1pass’;来同时建用户并赋权,但是现在我们使用下面的命令将会报错
GRANT app_developer TO ‘dev1’@’localhost’ IDENTIFIED BY ‘dev1pass’;
我们只能分开来操作:
create user ‘dev1’@’localhost’ IDENTIFIED BY ‘dev1pass’;
GRANT app_developer TO ‘dev1’@’localhost’;

这个时候mysql的role_edges表里就会多一条记录
root@mysql 03:44:38>select * from role_edges;
+———–+—————+———–+———+——————-+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+———–+—————+———–+———+——————-+
| % | app_developer | localhost | dev1 | N |
+———–+—————+———–+———+——————-+
1 row in set (0.00 sec)

我们和以前的版本一样来查看一下用户的权限:
root@mysql 03:45:42>show grants for ‘dev1’@’localhost’;
+————————————————-+
| Grants for dev1@localhost |
+————————————————-+
| GRANT USAGE ON *.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+————————————————-+
2 rows in set (0.00 sec)

root@mysql 03:45:53>show grants for ‘dev1’@’localhost’ using ‘app_developer’;
+——————————————————–+
| Grants for dev1@localhost |
+——————————————————–+
| GRANT USAGE ON *.* TO `dev1`@`localhost` |
| GRANT ALL PRIVILEGES ON `test`.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+——————————————————–+
3 rows in set (0.00 sec)

这个时候我们使用dev1刚刚建的用户登一下
$mysql -udev1 -pdev1pass

dev1@(none) 04:02:33>show databases;
+——————–+
| Database |
+——————–+
| information_schema |
+——————–+
1 row in set (0.01 sec)

dev1@(none) 04:02:39>SELECT CURRENT_ROLE();
+—————-+
| CURRENT_ROLE() |
+—————-+
| NONE |
+—————-+
1 row in set (0.00 sec)

dev1@(none) 04:02:54>select * from test.a;
ERROR 1142 (42000): SELECT command denied to user ‘dev1’@’localhost’ for table ‘a’

可以发现并查不了。
这个时候我们set一下当前的角色
dev1@(none) 04:04:33>set role app_developer;
Query OK, 0 rows affected (0.00 sec)

dev1@(none) 04:04:38>SELECT CURRENT_ROLE();
+———————+
| CURRENT_ROLE() |
+———————+
| `app_developer`@`%` |
+———————+
1 row in set (0.00 sec)

dev1@(none) 04:04:42>show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| test |
+——————–+
2 rows in set (0.00 sec)

当我们set了以后可以了。
当然我们也可以SET ROLE ALL 【EXCEPT xxx】 当有多个的时候也可以这个样子
我们每次都需要这样set太累了,我们也可以直接set default
root@mysql 04:30:18>SET DEFAULT ROLE app_developer TO ‘dev1’@’localhost’;
Query OK, 0 rows affected (0.00 sec)

root@mysql 04:30:19>select * from default_roles;
+———–+——+——————-+——————-+
| HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+———–+——+——————-+——————-+
| localhost | dev1 | % | app_developer |
+———–+——+——————-+——————-+
1 row in set (0.00 sec)

 

收回权限的时候可以使用
REVOKE role FROM user;
REVOKE privileges FROM role;

和role相关的系统参数
dba@(none) 04:50:44>show variables like ‘%role%’;
+—————————–+——-+
| Variable_name | Value |
+—————————–+——-+
| activate_all_roles_on_login | OFF |
| mandatory_roles | |
+—————————–+——-+
2 rows in set (0.00 sec)

dba@(none) 04:52:05>set global activate_all_roles_on_login=on;

https://dev.mysql.com/doc/refman/8.0/en/roles.html

MySQL8新特性-Mandatory Roles

强制角色:Mandatory roles
可以指定强制性的角色作为mandatory_roles系统变量的值。服务器将一个强制性的角色授予所有用户,所以它不需要明确授予任何帐户。
[mysqld]
mandatory_roles=’role1,role2@localhost,r3@%.example.com’
或者
SET PERSIST mandatory_roles = ‘role1,role2@localhost,r3@%.example.com’;
不过需要注意的是:
As of MySQL 8.0.4, setting mandatory_roles requires the ROLE_ADMIN privilege, in addition to the SYSTEM_VARIABLES_ADMIN or SUPER privilege normally required to set a global system variable.
Roles named in the value of mandatory_roles cannot be revoked with REVOKE or dropped with DROP ROLE or DROP USER.
SET PERSIST sets the value for the running MySQL instance. It also saves the value to be used for subsequent server restarts; see Section 13.7.5.1, “SET Syntax for Variable Assignment”. To change a value only for the running MySQL instance without saving it for subsequent restarts, use the GLOBAL keyword rather than PERSIST.

我们做一个示范:

首先建一个角色并授权:
CREATE ROLE ‘app_developer’;
GRANT ALL ON test.* TO ‘app_developer’;

然后我们把这个参数设成这个角色:
SET PERSIST mandatory_roles = ‘app_developer@%’;

然后我们创建一个用户 并不赋权
create user ‘test2’@’%’ identified by ‘test2’;
FLUSH PRIVILEGES;

我们在其它的窗口上用新加的这个帐号进去。然后可以直接set这个role
test2@information_schema 01:15:07>set role app_developer;
Query OK, 0 rows affected (0.00 sec)

也可以进行查询
test2@information_schema 01:15:15>show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| test |
+——————–+
2 rows in set (0.00 sec)

test2@information_schema 01:15:19>use test;
Database changed
test2@test 01:15:23>select * from test.a;
+——+
| id |
+——+
| 1 |
+——+
1 row in set (0.01 sec)

然后如果我们把这个参数改成空的,相应的权限也就没有了。 这个不用退出会话就会生效
test2@(none) 01:17:03>set role app_developer;
ERROR 3530 (HY000): `app_developer`@`%` is not granted to `test2`@`%`

需要注意的是 当一个角色被set了之后是不可以被删除的
dbadmin@(none) 01:20:25>drop role app_developer;
ERROR 4527 (HY000): The role `app_developer`@`%` is a mandatory role and can’t be revoked or dropped. The restriction can be lifted by excluding the role identifier from the global variable mandatory_roles.

MySQL8新特性-PERSIST

在以前是版本里我们set 一个参数的时候可以使用GLOBAL | SESSION和影响当前会话和全局的参数。但是即使是global的参数在重新启动实例以后也是会消失的。为此在MySQL8以后的版本引入了另外的两个语法参数,我们使用help set可以看到一共用了以下四个值。
[GLOBAL | SESSION | PERSIST | PERSIST_ONLY]
[@@global. | @@session. | @@persist. | @@persist_only. | @@]
简单来说PERSIST这是一个用来配置持续优化统计参数的语法。当我们set PERSIST system_var_name = expr的时候,我们可以在运行时进行配置更改并保存,在服务器重启后仍生效, 这个环境变量在修改的同时还会影响到数据文件目录的一个叫做mysqld-auto.cnf的文件,mysql在重新启动的时候,会优先使用这个文件里的参数值。mysql给我的建议是mysqld-auto.cnf文件应由管理服务器,而不是手动执行。我们先来简单的看一个例子

在修改之前我们先查看一下:
dba@(none) 10:39:24>select * from performance_schema.variables_info where VARIABLE_NAME=’mandatory_role;
+—————–+—————–+—————+———–+———–+———————+———-+———-+
| VARIABLE_NAME | VARIABLE_SOURCE | VARIABLE_PATH | MIN_VALUE | MAX_VALUE | SET_TIME | SET_USER | SET_HOST |
+—————–+—————–+—————+———–+———–+———————+———-+———-+
| mandatory_roles | COMPILED | | 0 | 0 | 2017-11-08 10:58:40 | | |
+—————–+—————–+—————+———–+———–+———————+———-+———-+
1 row in set (0.00 sec)

然后我们修改这个值:
SET PERSIST mandatory_roles = ‘app_developer@%’;

然后查看一下这个值的确是被修改了:
dba@(none) 10:40:43>
dba@(none) 10:40:43>select * from performance_schema.variables_info where VARIABLE_NAME=’mandatory_roles’;
+—————–+—————–+—————+———–+———–+———————+———-+———–+
| VARIABLE_NAME | VARIABLE_SOURCE | VARIABLE_PATH | MIN_VALUE | MAX_VALUE | SET_TIME | SET_USER | SET_HOST |
+—————–+—————–+—————+———–+———–+———————+———-+———–+
| mandatory_roles | DYNAMIC | | 0 | 0 | 2017-11-08 14:35:24 | dbadmin | localhost |
+—————–+—————–+—————+———–+———–+———————+———-+———–+
1 row in set (0.00 sec)

可以发现在我们的my.cnf文件里这个值并没有被修改。
$cat my.cnf | grep mandatory_roles

然后我们去数据文件所在的目录查看多出来的一个文件。
$cat mysqld-auto.cnf
{ “mysql_server”: {“mandatory_roles”: “app_developer@%”} }
可以看到是一个json格式的描述文件。
接下来我们重启数据库,然后查看当前参数的值。
dbadmin@(none) 10:52:49>show variables like ‘%mandatory_roles%’;
+—————–+—————–+
| Variable_name | Value |
+—————–+—————–+
| mandatory_roles | app_developer@% |
+—————–+—————–+
1 row in set (0.00 sec)

dba@(none) 10:55:11>select * from performance_schema.variables_info where VARIABLE_NAME=’mandatory_roles’\G
*************************** 1. row ***************************
VARIABLE_NAME: mandatory_roles
VARIABLE_SOURCE: PERSISTED
VARIABLE_PATH: /u01/my3306/data/mysqld-auto.cnf
MIN_VALUE: 0
MAX_VALUE: 0
SET_TIME: 2017-11-09 10:52:14
SET_USER:
SET_HOST:
1 row in set (0.00 sec)
可以发现还是修改过值。这也证明了我们的的配置进行了持久化。

那么我们怎么取消这个值设置呢。
有两种方法,它们略有一点不同
1.SET PERSIST mandatory_roles = DEFAULT;
2.RESET PERSIST IF EXISTS mandatory_roles;
在我们使用第一种方法的时候,mysqld-auto.cnf还是有这个值的,当我们再次重启的时候它还是读这个文件
$cat data/mysqld-auto.cnf
{ “mysql_server”: {“mandatory_roles”: “” } }
在我们使用第二种方法的时候就完全把这个参数的内容的去掉。
$cat data/mysqld-auto.cnf
{ “mysql_server”: { } }

使用第二种如果不存在的话:
dba@(none) 10:59:27>RESET PERSIST IF EXISTS mandatory_roles;
Query OK, 0 rows affected, 1 warning (0.00 sec)

dba@(none) 11:01:22>show warnings;
+———+——+——————————————————————+
| Level | Code | Message |
+———+——+——————————————————————+
| Warning | 3615 | Variable mandatory_roles does not exist in persisted config file |
+———+——+——————————————————————+
1 row in set (0.00 sec)

dba@(none) 11:01:27>RESET PERSIST mandatory_roles;
ERROR 3615 (HY000): Variable mandatory_roles does not exist in persisted config file

当然我们也可以只使用@@persist_only 来影响mysqld-auto.cnf的文件,在下次重启以后才生产。

整个的使用就像oralce的pfile和spfile。

如果你不想让mysqld-auto.cnf中的配置生效,可以在启动时关闭只读参数persisted_globals_load,这样在启动时就不会载入mysqld-auto.cnf中的配置项了

https://dev.mysql.com/doc/refman/8.0/en/set-variable.html?spm=5176.100239.blogcont60656.10.SVzv1S

MySQL8新特性-安装MySQL8.0.3

在官网上下载包以后解压然后安装依赖包
yum -y install gcc gcc-c++ gcc-g77 kernel-devel autoconf automake make cmake perl ncurses-devel libmcrypt* libtool-ltdl-devel* readline-devel pcre-devel openssl-devel openssl
我复制了一个5.7的my.cnf文件,在执行如下安装的时候报了以下的错:

./mysqld –defaults-file=/u01/my3306/my.cnf –initialize –user=mysql –basedir=/u01/mysql8.0 –datadir=/u01/my3306/data/

默认取消了query_cache相关的参数。
[ERROR] unknown variable ‘innodb_file_format=Barracuda’
[ERROR] unknown variable ‘log_warnings=1’
[ERROR] unknown variable ‘query_cache_limit=1M’
[ERROR] unknown variable ‘query_cache_type=0’
[ERROR] unknown variable ‘show_compatibility_56=on’

和5.7一样的 安装成功以后也是在alert.log里生产问题
2017-11-06T08:11:35.865054Z 5 [Note] A temporary password is generated for root@localhost: /8Kk-gIhJF+H

但是在起动的时候又报错了。
有些参数是在安装的时候去检查 有些参数则是在起动的时候才会去检查
2017-11-06 16:15:38 32381 [ERROR] /usr/sbin/mysqld: unknown variable ‘slave-parallel-type=LOGICAL_CLOCK’

可以看出来了多了很多sdi的文件 还有tablespaces 还有undo
$ls
auto.cnf ibdata1 ib_logfile0 ib_logfile2 ibtmp1 mysql_1.sdi performance_sche_3.sdi sys tablespaces.open.1 test undo_001
ib_buffer_pool ibdata2 ib_logfile1 ib_logfile3 mysql mysql.ibd performance_schema sys_4.sdi tablespaces.open.2 test_5.sdi undo_002
打开一个sdi查看可以看出来是json的描述文件
$cat test_5.sdi
{
“mysqld_version_id”: 80003,
“dd_version”: 1,
“sdi_version”: 1,
“dd_object_type”: “Schema”,
“dd_object”: {
“name”: “test”,
“default_collation_id”: 255,
“created”: 0,
“last_altered”: 0
}

进到mysql的文件里 可以看出来和以前的完全不一样

$ls
general_log_195.sdi general_log.CSM general_log.CSV slow_log_196.sdi slow_log.CSM slow_log.CSV

5.7版本如下:
[12-MySQL-Inst@db106 /u01/my3313/data/mysql]
$ls
columns_priv.frm event.MYI help_keyword.frm ndb_binlog_index.MYD proxies_priv.MYD slave_worker_info.ibd time_zone_name.frm
columns_priv.MYD func.frm help_keyword.ibd ndb_binlog_index.MYI proxies_priv.MYI slow_log.CSM time_zone_name.ibd
columns_priv.MYI func.MYD help_relation.frm plugin.frm server_cost.frm slow_log.CSV time_zone_transition.frm
db.frm func.MYI help_relation.ibd plugin.ibd server_cost.ibd slow_log.frm time_zone_transition.ibd
db.MYD general_log.CSM help_topic.frm proc.frm servers.frm tables_priv.frm time_zone_transition_type.frm
db.MYI general_log.CSV help_topic.ibd proc.MYD servers.ibd tables_priv.MYD time_zone_transition_type.ibd
db.opt general_log.frm innodb_index_stats.frm proc.MYI slave_master_info.frm tables_priv.MYI user.frm
engine_cost.frm gtid_executed.frm innodb_index_stats.ibd procs_priv.frm slave_master_info.ibd time_zone.frm user.MYD
engine_cost.ibd gtid_executed.ibd innodb_table_stats.frm procs_priv.MYD slave_relay_log_info.frm time_zone.ibd user.MYI
event.frm help_category.frm innodb_table_stats.ibd procs_priv.MYI slave_relay_log_info.ibd time_zone_leap_second.frm
event.MYD help_category.ibd ndb_binlog_index.frm proxies_priv.frm slave_worker_info.frm time_zone_leap_second.ibd

MySQL on Docker: Introduction to Docker Swarm Mode and Multi-Host Networking

主要介绍多主机网络的基本概念和Docker的Swarm模式,一个用于管理多台物理机上容器的内置编排工具;

— Docker引擎-Swarm模式;
把MySQL容器运行到多个宿主机上会根据选择的集群技术不同而变的复杂;

在我们尝试把MySQL运行在容器+多主机网络的环境中,必须要理解image是怎么工作的;有多少的资源(磁盘,内存,CPU)需要分配,网络(overlay网络的选择:默认,flannel,weave等)和容错性(容器是怎么重新分布,故障转移和负载均衡的);所有的这些都会影响整体的数据库操作,启动时间和性能;非常推荐在Docker引擎集群的上面使用一个编排工具来获得更好的管理性和扩展性;最新的Docker引擎(v1.12,2016.06.14发布的)包含了原生管理Docker引擎集群的工具,叫Swarm模式;Docker引擎的Swarm模式和Docker Swarm是两个不同的项目,尽管两者的工作原理很像,但是使用不同的安装步骤;

一些必要的知识:
1.必须要打开的端口:
1)2377(TCP):用于集群管理;
2)7946(TCP and UDP):用于节点间通信;
3)4789(TCP and UDP):overlay网络传输;
2.两种类型的节点:
1)Manager:管理节点执行编排和集群管理函数从而维护swarm的期望状态(desired state),管理节点选举出来一个leader来构建编排任务;
2)Worker:工作节点接收并执行管理节点分派的任务,默认情况下管理节点也是工作节点,但是可以配置管理节点只做管理节点;

这篇文章,准备部署应用容器到三台Docker宿主机(docker1, docker2, docker3)上,并使用Galera集群的负载均衡,通过多主机环境间的overlay网络进行网络连接;将使用Docker引擎的Swarm模式作为编排工具;

— 启动Swarm模式;
首先需要配置Docker节点到Swarm模式;Swarm模式需要奇数个(推荐三个,节点数越多效率越低)管理节点来维护错误时的法定人数;使用三台物理机器作为管理节点,默认的管理节点也是工作节点;

0.测试环境;
docker1.htsec.com 192.168.10.201
docker2.htsec.com 192.168.10.202
docker3.htsec.com 192.168.10.203

1.首先在docker1上初始化Swarm模式,会使得节点变成为Manager和Leader;
[root@docker1 ~]# docker swarm init –advertise-addr 192.168.10.201
Swarm initialized: current node (385guihkvrmuuuftm34ubr9v2) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join \
–token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-4370suyaolwu0ts8ujv3r7xy2 \
192.168.10.201:2377

To add a manager to this swarm, run ‘docker swarm join-token manager’ and follow the instructions.

2.准备把另外两台物理机也作为Manager,生成注册成为管理节点的命令;
[root@docker1 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:

docker swarm join \
–token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-2mnogcl6y71n85msftv40vbnb \
192.168.10.201:2377

3.在节点docker2和节点docker3分别执行命令注册为管理节点;
[root@docker2 ~]# docker swarm join \
> –token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-2mnogcl6y71n85msftv40vbnb \
> 192.168.10.201:2377
This node joined a swarm as a manager.

[root@docker3 ~]# docker swarm join \
> –token SWMTKN-1-43yqmld4mddoddnaxpslsg9s6abxfkkzrbprizzqoofad4rma1-2mnogcl6y71n85msftv40vbnb \
> 192.168.10.201:2377
This node joined a swarm as a manager.

4.验证所有的节点;
[root@docker1 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
385guihkvrmuuuftm34ubr9v2 * docker1.htsec.com Ready Active Leader
63o59qn38i70iej61h7edm1s1 docker3.htsec.com Ready Active Reachable
ahorta43as7m7yupv3bsnc7pg docker2.htsec.com Ready Active Reachable

此时docker1.htsec.com是Leader节点;

— overlay网络;
使运行在不同宿主机上的容器可以互相通信的唯一方法是使用overlay网络;可以认为,容器的网络是构建在其它的网络之上的(在这个环境中,是构建在宿主机网络上的);Docker Swarm模式的默认overlay网络实现了一个基于VxLAN的解决方案,底层依赖于libnetwork和libkv库,所以overlay网络需要一个key-value存储服务,用于在不同的docker引擎间交换信息;可以选择使用其他外部的overlay网络驱动(比如Flannel,Calico或者Weave),但是需要额外的安装步骤;

使用Docker引擎的Swarm模式,可以在管理节点创建一个overlay网络,不需要外部的key-value存储(比如etcd,consul或者Zookeeper);

Swarm会使overlay网络在需要运行服务的节点上都有效;当你创建一个使用overlay网络的服务,管理节点会自动扩展overlay网络到运行服务任务的节点;

首先创建一个overlay网络,来把Percona XtraDB Cluster和应用容器运行在不同的Docker服务器上,从而达到容灾的效果;这些容器必须运行在同一个overlay网络上,以至于它们可以互相通信;

1.首先创建一个叫”mynet”的overlay网络,这个网络只能在管理节点创建;
[root@docker1 ~]# docker network create –driver overlay mynet
32tayer754amlqnwti9a0c4ht

2.查看当前环境的网络状况;
[root@docker1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
9e1f395cbd90 bridge bridge local
3c63a1302938 docker_gwbridge bridge local
3996de1d0f28 host host local
3uvc0j5s4t1y ingress overlay swarm
32tayer754am mynet overlay swarm
3e1b264a2086 none null local

在swarm范围内有两个overlay网络,”mynet”网络是刚刚创建并用于部署MySQL集群的网络,”ingress”网络是默认的overlay网络;Swarm的Manager使用”ingress”来实现服务间的负载均衡;

— 使用服务和任务进行部署;
计划使用服务和任务来部署Galera Cluster容器;当创建一个服务,需要指定使用哪一个容器镜像和在运行的容器里面运行哪些命令;

有两种类型的服务:
1)Replicated services:基于设置的期望状态(desired state),会在集群的节点上分布指定数量的任务来达到扩展的目的,例如:”–replicas 3″;
2)Global services:集群中每一个可用的节点上都运行一个服务的任务,例如:”–mode global”;如果在swarm中有7个docker节点,则每一个节点都会运行一个容器;

Docker Swarm模式在管理持久性数据存储方面有一定的局限,当一个节点失败,Manager会除掉这个容器并且创建一个新的来替换旧的,从而达到期望状态;因为一个容器失败后会被丢弃,相应的也会失去数据卷;幸运的是,对于Galera集群来说,当新的MySQL容器可以自动的达到相应状态;

— 部署Key-Value存储;
使用的Docker镜像来自Percona,当集群初始化和引导时,这个镜像需要MySQL容器访问一个key-value存储(仅支持etcd),从而来发现相应的IP地址;这些容器会从etcd中查看其它的IP地址,如果保存的有IP地址,则会使用一个适合的wsrep_cluster_address参数来启动MySQL,否则,第一个容器会使用”gcomm://”来作为引导地址;

1.首先在docker1上运行一个etcd服务(也可以使用服务发现的方式);
[root@docker1 ~]# export HostIP=”192.168.10.201″
[root@docker1 ~]# docker run -d -p 2379:2379 -p 2380:2380 -p 4001:4001 –name etcd elcolio/etcd \
> -name etcd1 \
> -advertise-client-urls http://${HostIP}:2379,http://${HostIP}:4001 \
> -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:4001 \
> -initial-advertise-peer-urls http://${HostIP}:2380 \
> -listen-peer-urls http://0.0.0.0:2380 \
> -initial-cluster-token etcd-cluster \
> -initial-cluster etcd1=http://${HostIP}:2380 \
> -initial-cluster-state new
fc994bb85036b57bef06e55e1856ef1c6f12198b7700744a9be61c22ea62f170
[root@docker1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc994bb85036 elcolio/etcd “/bin/run.sh -name et” 6 seconds ago Up 4 seconds 0.0.0.0:2379-2380->2379-2380/tcp, 0.0.0.0:4001->4001/tcp, 7001/tcp etcd

2.此时可以通过http://192.168.10.201:2379访问etcd服务(如果是使用服务启动的etcd,可以通过命令:docker service inspect etcd -f “{{ .Endpoint.VirtualIPs }}”查看);
[root@docker1 ~]# curl http://192.168.10.201:2379/v2/members
{“members”:[{“id”:”e4379b6d6b63f88c”,”name”:”etcd1″,”peerURLs”:[“http://192.168.10.201:2380″],”clientURLs”:[“http://192.168.10.201:2379″,”http://192.168.10.201:4001”]}]}

— 部署数据库集群;
1.在部署Galera(Percona XtraDB Cluster)容器的命令中指定etcd的服务地址;
[root@docker1 ~]# docker service create –name mysql-galera –replicas 3 \
> -p 3306:3306 –network mynet \
> –env MYSQL_ROOT_PASSWORD=mypassword \
> –env DISCOVERY_SERVICE=192.168.10.201:2379 \
> –env XTRABACKUP_PASSWORD=mypassword \
> –env CLUSTER_NAME=galera \
> percona/percona-xtradb-cluster
b8uica0izpvytrtw097csjfrz

2.查看服务的状态,会发现在三个节点上分别运行了percona-xtradb-cluster容器;
[root@docker1 ~]# docker service ps mysql-galera
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
eknbellxg7y3zpujxzmv05dd5 mysql-galera.1 percona/percona-xtradb-cluster docker1.htsec.com Running Running 30 seconds ago
67bs9tu87zt81mjn5salk4rtn mysql-galera.2 percona/percona-xtradb-cluster docker3.htsec.com Running Running 30 seconds ago
6njkyk7pj4r02rdef3ihikrcj mysql-galera.3 percona/percona-xtradb-cluster docker2.htsec.com Running Running 30 seconds ago

3.查看mysql-galera服务的状态,正在正常运行;
[root@docker1 ~]# docker service ls
ID NAME REPLICAS IMAGE COMMAND
b8uica0izpvy mysql-galera 3/3 percona/percona-xtradb-cluster

4.Swarm模式内部的DNS组件可以自动的给服务的每个任务分配IP,所以可以通过服务名查看到对应的虚拟IP地址;
[root@docker1 ~]# docker service inspect mysql-galera -f “{{ .Endpoint.VirtualIPs }}”
[{3uvc0j5s4t1yuzi9yfxmt4s22 10.255.0.6/16} {32tayer754amlqnwti9a0c4ht 10.0.0.2/24}]

https://www.percona.com/blog/2016/06/10/percona-xtradb-cluster-in-a-multi-host-docker-network/
http://severalnines.com/blog/mysql-docker-introduction-docker-swarm-mode-and-multi-host-networking
https://hub.docker.com/r/percona/percona-xtradb-cluster/

2016-11-21T14:38:09.786753Z 0 [ERROR] WSREP: failed to open gcomm backend connection: 131: No address to connect (FATAL)
at gcomm/src/gmcast.cpp:connect_precheck():286
2016-11-21T14:38:09.786761Z 0 [ERROR] WSREP: gcs/src/gcs_core.cpp:gcs_core_open():208: Failed to open backend connection: -131 (State not recoverable)
2016-11-21T14:38:09.786921Z 0 [ERROR] WSREP: gcs/src/gcs.cpp:gcs_open():1407: Failed to open channel ‘galera’ at ‘gcomm://10.255.0.9,10.255.0.7,10.255.0.9’: -131 (State not recoverable)
2016-11-21T14:38:09.786930Z 0 [ERROR] WSREP: gcs connect failed: State not recoverable
2016-11-21T14:38:09.786933Z 0 [ERROR] WSREP: wsrep::connect(gcomm://10.255.0.9,10.255.0.7,10.255.0.9) failed: 7

— 相关技术;
1.VXLAN(Virtual eXtensible LAN,可扩展虚拟局域网):是基于IP网络之上,采用的是MAC in UDP技术,本来OSI七层模型里就是一层叠一层的,这种和GRE/IPSEC等tunnel技术是不是很像,这种封装技术对中间网络没有特殊要求,只要你能识别IP报文即可进行传送;

2.为何需要Vxlan:
1)虚拟机规模受到网络规格的限制,大L2网络里,报文通过查询MAC地址转发,MAC表容量限制了虚拟机的数量;
2)网络隔离的限制,普通的VLAN和VPN配置无法满足动态网络调整的需求,同时配置复杂;
3)虚拟器搬迁受到限制,虚拟机启动后假如在业务不中断基础上将该虚拟机迁移到另外一台物理机上去,需要保持虚拟机的IP地址和MAC地址等参数保持不变,这就要求业务网络是一个二层的网络;

MySQL on Docker: Multi-Host Networking for MySQL Containers

这篇文章会在基于Calico网络驱动的多台宿主机上部署MySQL Replication;

Docker v1.12版本的Swarm模式是一个原生的编排工具,然而它不支持其它的网络插件(比如Calico,Weave,Flannel);如果想要运行这些网络插件,必须在Swarm模式外面运行,并且使用其它的编排工具(Kubernetes, Mesos 或者 Docker Swarm);

Calico不能被称为”overlay network”,这意味着它不会将一个数据包封装在另一个数据包中;它使用纯第3层方法,并避免与第2层解决方案相关联的数据包封装,这简化了诊断,减少了传输开销并提高了性能;Calico还实现BGP协议,用于与纯IP网络相结合的路由,从而允许虚拟网络的因特网扩展;

— 测试环境,三台宿主机都安装了Docker引擎v1.12.3版本;
192.168.10.201 docker1.htsec.com docker1
192.168.10.202 docker2.htsec.com docker2
192.168.10.203 docker3.htsec.com docker3

— Key-Value存储(etcd);
etcd是一个开源的分布式键值存储,主要用于配置共享和服务发现;一个简单的应用场景是存储数据库的连接或者是特性标示;

Calico需要etcd进行操作;etcd可以使用多个实例进行集群,例子中使用三个节点的etcd集群来保证高可用性;

1.分别安装etcd包;
yum install -y etcd;

2.修改相应的配置文件;
[root@docker1 ~]# vi /etc/etcd/etcd.conf
ETCD_NAME=etcd1
ETCD_LISTEN_PEER_URLS=”http://0.0.0.0:2380″
ETCD_LISTEN_CLIENT_URLS=”http://0.0.0.0:2379″
ETCD_INITIAL_ADVERTISE_PEER_URLS=”http://192.168.10.201:2380″
ETCD_INITIAL_CLUSTER=”etcd1=http://192.168.10.201:2380,etcd2=http://192.168.10.202:2380,etcd3=http://192.168.10.203:2380″
ETCD_INITIAL_CLUSTER_STATE=”new”
ETCD_INITIAL_CLUSTER_TOKEN=”etcd-cluster-1″
ETCD_ADVERTISE_CLIENT_URLS=”http://0.0.0.0:2379″

[root@docker2 ~]# vi /etc/etcd/etcd.conf
ETCD_NAME=etcd2
ETCD_LISTEN_PEER_URLS=”http://0.0.0.0:2380″
ETCD_LISTEN_CLIENT_URLS=”http://0.0.0.0:2379″
ETCD_INITIAL_ADVERTISE_PEER_URLS=”http://192.168.10.202:2380″
ETCD_INITIAL_CLUSTER=”etcd1=http://192.168.10.201:2380,etcd2=http://192.168.10.202:2380,etcd3=http://192.168.10.203:2380″
ETCD_INITIAL_CLUSTER_STATE=”new”
ETCD_INITIAL_CLUSTER_TOKEN=”etcd-cluster-1″
ETCD_ADVERTISE_CLIENT_URLS=”http://0.0.0.0:2379″

[root@docker3 ~]# vi /etc/etcd/etcd.conf
ETCD_NAME=etcd3
ETCD_LISTEN_PEER_URLS=”http://0.0.0.0:2380″
ETCD_LISTEN_CLIENT_URLS=”http://0.0.0.0:2379″
ETCD_INITIAL_ADVERTISE_PEER_URLS=”http://192.168.10.203:2380″
ETCD_INITIAL_CLUSTER=”etcd1=http://192.168.10.201:2380,etcd2=http://192.168.10.202:2380,etcd3=http://192.168.10.203:2380″
ETCD_INITIAL_CLUSTER_STATE=”new”
ETCD_INITIAL_CLUSTER_TOKEN=”etcd-cluster-1″
ETCD_ADVERTISE_CLIENT_URLS=”http://0.0.0.0:2379″

3.分别启动docker1,docker2和docker3上的etcd服务;
systemctl start etcd.service
systemctl enable etcd.service

4.检查etcd集群状态;
[root@docker1 ~]# etcdctl member list
29868e609fc76b11: name=etcd3 peerURLs=http://192.168.10.203:2380 clientURLs=http://0.0.0.0:2379 isLeader=false
6ebf0a399d4f3850: name=etcd1 peerURLs=http://192.168.10.201:2380 clientURLs=http://0.0.0.0:2379 isLeader=true
af11bb15f5145af9: name=etcd2 peerURLs=http://192.168.10.202:2380 clientURLs=http://0.0.0.0:2379 isLeader=false
[root@docker1 ~]# etcdctl cluster-health
member 29868e609fc76b11 is healthy: got healthy result from http://0.0.0.0:2379
member 6ebf0a399d4f3850 is healthy: got healthy result from http://0.0.0.0:2379
member af11bb15f5145af9 is healthy: got healthy result from http://0.0.0.0:2379
cluster is healthy

— 安装Calico;
1.下载Calico并使它可执行;
$ wget http://www.projectcalico.org/builds/calicoctl -P /usr/local/bin
$ chmod +x /usr/local/bin/calicoctl

2.在docker1上创建calico节点,指定Docker宿主机的IP地址;

docker run -d –restart=always –net=host –privileged –name=calico-node \
-e HOSTNAME=docker1.htsec.com -e IP=192.168.10.201 \
-e IP6= -e CALICO_NETWORKING_BACKEND=bird -e AS= -e NO_DEFAULT_POOLS= \
-e ETCD_AUTHORITY=127.0.0.1:2379 -e ETCD_SCHEME=http \
-v /var/log/calico:/var/log/calico -v /lib/modules:/lib/modules \
-v /var/run/calico:/var/run/calico \
calico/node:latest

docker run -d –restart=always –net=host –privileged –name=calico-node \
-e HOSTNAME=docker2.htsec.com -e IP=192.168.10.202 \
-e IP6= -e CALICO_NETWORKING_BACKEND=bird -e AS= -e NO_DEFAULT_POOLS= \
-e ETCD_AUTHORITY=127.0.0.1:2379 -e ETCD_SCHEME=http \
-v /var/log/calico:/var/log/calico -v /lib/modules:/lib/modules \
-v /var/run/calico:/var/run/calico \
calico/node:latest

docker run -d –restart=always –net=host –privileged –name=calico-node \
-e HOSTNAME=docker3.htsec.com -e IP=192.168.10.203 \
-e IP6= -e CALICO_NETWORKING_BACKEND=bird -e AS= -e NO_DEFAULT_POOLS= \
-e ETCD_AUTHORITY=127.0.0.1:2379 -e ETCD_SCHEME=http \
-v /var/log/calico:/var/log/calico -v /lib/modules:/lib/modules \
-v /var/run/calico:/var/run/calico \
calico/node:latest

TODO:
http://severalnines.com/blog/mysql-docker-multi-host-networking-mysql-containers-part-2-calico

MySQL on Docker: Single Host Networking for MySQL Containers

对于MySQL来说,网络是非常关键的,它是管理客户端访问服务器和集群节点之间访问的基础资源;容器化的MySQL服务行为取决于MySQL镜像如何使用docker run命令衍生出容器;使用Docker单主机网络,MySQL容器可以运行于一个独立的环境(只能访问相同网络的容器),或者一个开放的环境(通过端口映射,MySQL服务完全暴露到外部),或者运行一个完全无网络的实例;

— 三种类型的网络;
默认情况下,Docker在安装的时候会在宿主机上创建三种类型的网络:
[root@docker ~]# docker network ls;
NETWORK ID NAME DRIVER SCOPE
4c18ec95ca54 bridge bridge local
5c10d699ceb7 host host local
e0ce99953647 none null local

1.主机网络;
主机网络在宿主机的网络堆栈上添加一个容器,可以想象为在此网络中运行的容器正在连接到与宿主机相同的网络接口;它有以下特点:
1)容器的网络接口与宿主机是相同的;
2)每个宿主机只能有一个主机网络,不能创建更多;
3)如果要分配一个容器使用此网络,需要在docker run命令中显示指定”–net=host”参数;
4)不支持容器链接(比如:–link mysql-container:mysql);
5)不支持端口映射(比如:-p 3307:3306);

使用”–net=host”参数在主机网络上创建一个容器:docker run -d –restart=always –name=mysql-host –net=host -e MYSQL_ROOT_PASSWORD=pwd mysql

进入容器并查看对应的网络接口,发现与宿主机一样:
[root@docker ~]# docker exec -it mysql-host /bin/bash
root@docker:/# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:9c:e6:2d brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
valid_lft 84565sec preferred_lft 84565sec
inet6 fe80::a00:27ff:fe9c:e62d/64 scope link
valid_lft forever preferred_lft forever
3: enp0s8:
mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:95:f6:b6 brd ff:ff:ff:ff:ff:ff
inet 192.168.10.100/24 brd 192.168.10.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe95:f6b6/64 scope link
valid_lft forever preferred_lft forever
4: docker0: mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:8c:49:90:73 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever

这种设置下,容器不需要在防火墙中设置任何的转发规则,因为它已经与主机网络连接了;因此也就不再支持端口映射了;

如果想要查看主机上某个端口是否在监听:[root@docker ~]# netstat -tulpn | grep 3306 (yum install -y net-tools)
tcp6 0 0 :::3306 :::* LISTEN 3572/mysqld

把MySQL容器以主机网络模式运行在宿主机上与直接标准安装到宿主机上是相似的,唯一的好处是有一个独立的MySQL服务器,尽管是Docker管理的;

基于主机网络创建的容器可以被基于默认桥网络docker0和用户自定义的桥网络创建的容器直接访问;

2.桥网络;
桥接允许同一台物理主机上的多个网络保持分离并独立通信;可以想象成这类似于宿主机的另一个内部网络,只有处于同一网络的容器才能访问其它的容器和主机,如果主机可以连接广域网,则容器也可以;

有两种类型的桥网络:1)默认的桥网络(docker0);2)用户定义的桥网络;

1)默认的桥网络(docker0):
在Docker安装的时候会自动创建docker0,可以通过”ip addr”命令进行验证;默认的IP范围是172.17.0.1/16,可以通过配置文件(Debian:/etc/default/docker;RedHat:/etc/sysconfig/docker)进行修改;

一般的,如果运行docker run命令时不指定–net参数,Docker会默认使用docker0网络创建容器;
[root@docker ~]# docker run -d –restart=always –name=mysql-bridge -p 3307:3306 -e MYSQL_ROOT_PASSWORD=pwd mysql

进入容器并查看对应的网络接口,Docker创建了一个网络接口eth0:
[root@docker ~]# docker exec -it mysql-bridge /bin/bash
root@db0336cafef9:/# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
5: eth0@if6: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever

默认情况下,Docker使用iptables来管理转发到桥网络的包;每个传出连接将显示为源自某一个宿主机自己的IP地址;以下是上述容器启动后宿主机的NAT链:
[root@docker ~]# iptables -L -n -t nat
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all — 172.17.0.0/16 0.0.0.0/0
MASQUERADE tcp — 172.17.0.2 172.17.0.2 tcp dpt:3306

Chain DOCKER (2 references)
target prot opt source destination
RETURN all — 0.0.0.0/0 0.0.0.0/0
DNAT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:3307 to:172.17.0.2:3306

上面的规则允许3307端口基于docker run命令中端口映射选项”-p 3307:3306″暴露在宿主机上;如果查看主机上的netstat分析,会发现MySQL时监听在3307端口的,并且属于docker-proxy进程;
[root@docker ~]# netstat -tulpn | grep 3307
tcp6 0 0 :::3307 :::* LISTEN 3916/docker-proxy

默认的桥网络支持端口映射和容器链接,如果想要链接到其它的容器,可以使用docker run命令的”–link”选项,容器会自动暴露环境变量并且通过/etc/hosts文件自动配置主机映射;

2)用户自定义桥网络:
Docker允许创建自定义的桥网络(也可以创建自定义的overlay网络),它的行为与docker0网络一致,网络中每一个容器都可以立即与其它容器通信;网络本身与外部的网络是隔离的;

这种网络的最大的优点是所有的容器都有解析容器名字的能力:
s1:首先创建一个自定义桥网络:
[root@docker ~]# docker network create –driver=bridge mysql-network

s2:基于用户定义网络创建5个mysql容器;
[root@docker ~]# for i in {1..5}; do docker run -d –name=mysql$i –net=mysql-network -e MYSQL_ROOT_PASSWORD=pwd mysql; done

s3:登陆其中任意一个容器,然后ping其它所有的容器;
root@docker ~]# docker exec -it mysql3 /bin/bash
root@eb3ba9f5ffc5:/# for i in {1..5}; do ping -c 1 mysql$i ; done
PING mysql1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.099 ms
— mysql1 ping statistics —
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.099/0.099/0.099/0.000 ms
PING mysql2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.097 ms
— mysql2 ping statistics —
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.097/0.097/0.097/0.000 ms
PING mysql3 (172.18.0.4): 56 data bytes
64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.055 ms
— mysql3 ping statistics —
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.055/0.055/0.055/0.000 ms
PING mysql4 (172.18.0.5): 56 data bytes
64 bytes from 172.18.0.5: icmp_seq=0 ttl=64 time=0.069 ms
— mysql4 ping statistics —
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.069/0.069/0.069/0.000 ms
PING mysql5 (172.18.0.6): 56 data bytes
64 bytes from 172.18.0.6: icmp_seq=0 ttl=64 time=0.067 ms
— mysql5 ping statistics —
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.067/0.067/0.067/0.000 ms

s4:查看DNS配置,发现Docker配置了一个内置的DNS服务器;
[root@docker ~]# docker exec -it mysql3 /bin/bash
root@eb3ba9f5ffc5:/# cat /etc/resolv.conf
search htsec.com
nameserver 127.0.0.11
options ndots:0
root@eb3ba9f5ffc5:/#

内置的DNS服务器维护了容器名称到它IP地址的映射关系,这个网络里面的所有容器都会指向此DNS服务器;这个特性可以用于网络中的节点发现,而且对于构建一个MySQL容器集群特别有用,可选的集群技术有MySQL复制,Galera集群或者MySQL集群;

Default vs User-defined Bridge
Area Default bridge (docker0) User-defined bridge
Network deployment Docker creates upon installation Created by user
Container deployment Default to this network Explicitly specify “–net=[network-name]” in
the “docker run” command
Container linking Allows you to link multiple containers Not supported
together and send connection information
from one to another by using
“–link [container-name]:[service-name]”.
When containers are linked, information
about a source container can be sent to
a recipient container.
Port mapping Supported e.g, by using “-p 3307:3306” Supported e.g, by using “-p 3307:3306”
Name resolver Not supported (unless you link them) All containers in this network are able to
resolve each other’s container name to IP address.
Version <1.10 use /etc/hosts, >=1.10 use embedded
DNS server.
Packet forwarding Yes, via iptables Yes, via iptables
Example usage for MySQL MySQL standalone MySQL replication, Galera Cluster, MySQL Cluster
(involving more than one MySQL container setup)

3.无网络;
同样可以利用docker run命令并指定”–net=none”选项创建一个不依附于任何网络的容器,这种容器只能通过交互的shell访问,容器里面不会配置任何附加的网络接口;
[root@docker ~]# docker run -d –restart=always –name=mysql-none –net=none -e MYSQL_ROOT_PASSWORD=pwd mysql

进入容器并查看相应的网络:
[root@docker ~]# docker exec -it mysql-none /bin/bash
root@3e0b1012db86:/# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever

无网络中的容器不能加入任何网络,然而MySQL容器依然可以运行并且可以直接使用mysql客户端进行访问;

使用场景:可以运行一个MySQL容器做备份恢复验证;

MySQL OCP-18-性能调节简介

— 影响性能的因素;
1.环境问题,MySQL的性能受主机的性能特征影响:
1.CPU速度和数量;
2.磁盘I/O;
3.网络性能;
4.操作系统争用;
2.MySQL配置:
1.数据库设计:索引,数据类型(合适且尽可能小),标准化;
2.应用程序性能:特定请求(仅请求特定的行和列),短时事务(根据主键访问的短事务);
3.配置变量:调整缓冲区,高速缓存,InnoDB设置;

— 监视;
1.要调节服务器的性能,必须了解其性能特征;可以针对整体性能进行基准测试,也可以使用日志和EXPLAIN逐个分析事件或者使用ERFORMANCE_SCHEMA按组分析事件;
2.基准测试:
1.mysqlslap:是标准MySQL分发的一部分,是一个基准测试工具,用来模拟MySQL服务器实例上客户机负载,并显示每个阶段的计时信息;
2.sql-bench:是MySQL源码分发的一部分,它是一系列Perl脚步,用于执行多个语句和手机状态计时数据;
3.分析:
1.日志:
1.一般查询日志;
2.慢查询日志;
2.语句:
1.EXPLAIN;
2.PROCEDURE ANALYSE;
3.SHOW STATUS:还可以使用mysqladmin extended-status查看;
4.PERFORMANCE_SCHEMA数据库;

— 性能模式;
“性能模式”是在较低级别监视MySQL服务器执行情况的功能:
1.该功能是使用PERFORMANCE_SCHEMA存储引擎和performance_schema数据库实现的;
2.性能模式监视并允许您检查MySQL服务器中的被检测代码的性能特征:
1.开发者将检测函数和其他编码事件以收集计时信息;
2.公开的性能数据对以下人员或任务很有帮助:
1.MySQL代码库的贡献者;
2.插件开发者;
3.识别低级别的性能瓶颈,如日志文件I/O等待或缓冲池互斥;
3.从Oracle下载的所有二进制版本的MySQL中都提供了性能模式;默认情况下,将启用性能模式,并在服务器启动时使用performance_schema变量对其进行控制;
mysql> SHOW VARIABLES LIKE ‘performance_schema’;
mysql> SHOW TABLE STATUS FROM performance_schema\G

— 检测,实例,事件和使用者;
性能模式数据库包含配置和事件信息:
1.性能模式中的“检测”是服务器代码中引发要监视的事件的点;
1.每个检测由其类型/所属的模块/该特定检测的变量或类组成,通过查performance_schema.setup_instruments表可查看所有可用的检测;
2.性能模式将记录实例表中的每个检测实例;例如,以下查询显示检测wait/io/file/sql/FRM记录文件实例/var/lib/mysql/mem/tags.frm上的事件;
mysql> SELECT file_name, event_name FROM file_instances LIMIT 1\G *************************** 1. row ***************************
FILE_NAME: /var/lib/mysql/mem/tags.frm
EVENT_NAME: wait/io/file/sql/FRM
2.每个被检测的对象都是该检测的一个“实例”,记录在一系列实例表中;
3.当线程执行检测实例中的代码时,MySQL将识别所发生的“事件”,将其记录在事件和汇总表中;
4.每个“使用者”都是性能模式中表的名称,用于记录和查询事件以及事件的摘要,在SETUP_CONSUMERS表中进行配置;每个使用者的NAME是性能模式中用于查询事件和摘要的表的名称,被禁用的使用者不记录信息,从而节省了系统资源;
mysql> SELECT * FROM setup_consumers;
5.当MySQL识别了发生在检测实例中的事件后,会将其记录在事件表中:
1.主事件表为events_waits_current,该表中存储了每个线程最近的事件;
2.events_waits_history存储每个线程的最近10个事件;
3.events_waits_history_long共存储10,000个最近事件;
6.当使用性能模式识别瓶颈或其他问题时,请执行以下操作:
1.确保已针对适用于您所遇到的问题类型的一系列检测和使用者启用了性能模式;例如,如果您确定问题出在I/O限制上,请使用wait/io/file/*检测;如果不确定根本原因,请使用更广范围的检测;
2.运行用于产生该问题的测试用例;
3.查询events_waits_*表等使用者,尤其是使用适用的WHERE子句过滤器查询events_waits_history_long,以便进一步缩小问题原因的范围;
4.禁用那些用于评估已排除的问题的检测;
5.重试该测试用例;

— 一般数据库优化;
1.对数据进行标准化可以:
1.标准化是移除数据库中的冗余和不当依赖关系(以避免将相同的数据存储在多个地方以及出现异常的风险)的行为;
2.标准化通常会产生以下结果:许多表的列变少,整体存储要求降低,I/O需求降低以及单次插入,更新和删除操作加快;
3.这提高了频繁执行小更新的事务性工作负荷的性能,但会使检索大量数据的查询变得复杂;
2.选择正确的数据类型和大小可以:
1.选择正确的数据类型是表设计中一个很重要却常常被忽视的部分,数据类型的大小可能会对表操作产生较大的影响;例如,选择将SMALLINT数字存储为INT会使该列所需的空 间翻倍,在包含一百万个行的表中,该决策将导致浪费额外的2MB存储空间,并且磁盘操作速度会变慢,缓冲区和高速缓存将需要使用更多内存;
2.使用INSERT…COMPRESS(field_name)…和SELECT…UNCOMPRESS(column_name)…可以在存储和检索字符串数据时对其进行压缩和解压缩;尽管也可以使用CHAR或VARCHAR字段来实现此目的,但是通过使用VARBINARY或BLOB列存储压缩数据可以避免字符集转换出现问题;
3.创建最佳索引可以:
1.如果您通过在WHERE子句中指定一个字段来查询表中的特定行,并且该表没有为该字段创建索引,MySQL将读取该表中的每一行以找到每个匹配的行;这将导致很多不必要的磁盘访问,并且对于大型表性能将显著降低;
2.索引是有序的成组数据,通过索引,MySQL可以更容易地找到查询行的正确位置;默认情况下,InnoDB将按主键排列表的顺序,该有序表称为群集索引;
3.InnoDB表上的每个附加索引或辅助索引会在文件系统中占用额外的空间,因为索引包含索引字段的额外副本以及主键的副本;
4.每次使用INSERT/UPDATE/REPLACE/DELETE操作修改数据时,MySQL也必须更新所有包含修改字段的索引,因此,向表中添加多个索引会降低影响该表的数据修改操作的性能;
5.不过,如果对索引进行了适当设计,依赖于索引字段的查询便会在性能上有较大的获益;如果查询无法使用索引找到特定行,则必须执行全表扫描;即,必须读取整个表来找到该行;

— PROCEDURE ANALYSE;
1.PROCEDURE ANALYSE分析给定查询中的列,并提供对每个字段的调节反馈:mysql> SELECT CountryCode, District, Population FROM City PROCEDURE ANALYSE(250,1024)\G
2.提供参数来调节如何建议ENUM值:
1.处理列时所使用的最大元素数和最大内存;
2.示例:…PROCEDURE ANALYSE(100,256);
3.用于最大程度地减小字段大小:
1.MySQL通常按最大的字段大小分配内存;
2.隐式MEMORY临时表,排序缓冲区等;
4.用于确定字段是否允许NULL;

补充:
1.默认设置通常建议使用ENUM类型来优化表的设计,如果确定不想在分析列时使用PROCEDURE ANALYSE()所建议的ENUM值,请使用非默认参数:
1.第一个参数是分析ENUM值是否适当时要考虑的不同元素数,此参数的默认值为256;
2.第二个参数是用于收集不同的值以供分析的最大内存量,此参数的默认值为8192,表示8KB;如果为此参数设置值0,则PROCEDURE ANALYSE()无法检查不同的值以建议使用ENUM类型;
2.如果PROCEDURE ANALYSE()无法存储可接受范围内的候选ENUM值(在参数设置的限制内),则不会建议对该列使用ENUM类型;
3.本幻灯片中的示例建议对City.CountryCode列使用CHAR(3)类型;另一方面,如果使用默认参数,则PROCEDURE ANALYSE()将建议ENUM(‘ABW’,’AFG’,…,’ZMB’,’ZWE’),这是一种包含超过200个元素的ENUM类型,其中针对每个相应的CountryCode值都包含一个不同值;

— EXPLAIN;
1.EXPLAIN命令:
1.描述MySQL打算如何执行特定的SQL语句;
2.不返回数据集的任何数据;
3.提供有关MySQL打算如何执行该语句的信息;
2.使用EXPLAIN可检查SELECT/INSERT/REPLACE/UPDATE/DELETE语句;
3.将EXPLAIN置于语句之前:
1.EXPLAIN SELECT …;
2.EXPLAIN UPDATE…;

补充:
1.EXPLAIN将为语句中使用的每个表生成一行输出,该输出包含以下列:
1.id:编号;若没有子查询和联合查询,id则都是1;MySQL会按照id从大到小的顺序执行query,在id相同的情况下,则从上到下执行;
2.select_type:查询中使用的选择类型;
3.table:输出的行所引用的表;有时看到的是,其中N对应的是id列的值;
4.partitions:输出行所对应的表分区;
5.type:访问类型,连接的方式;
6.possible_keys:在查询过程中可能用到的索引;在优化初期创建该列,但在以后的优化过程中会根据实际情况进行选择,所以在该列列出的索引在后续过程中可能没用;该列为NULL意味着没有相关索引,可以根据实际情况看是否需要加索引;
7.key:访问过程中实际用到的索引;有可能不会出现在possible_keys中(这时可能用的是覆盖索引,即使query中没有where);possible_keys揭示哪个索引更有效,key是优化器决定哪个索引可能最小化查询成本,查询成本基于系统开销等总和因素,有可能是“执行时间”矛盾;如果强制mysql使用或者忽略possible_keys中的索引,需要在query中使用FORCE INDEX,USE INDEX或者IGNORE INDEX;
8.key_len:显示使用索引的字节数;由根据表结构计算得出,而不是实际数据的字节数;如ColumnA(char(3)) ColumnB(int(11)),在utf-8的字符集下,key_len=3*3+4=13;计算该值时需要考虑字符列对应的字符集,不同字符集对应不同的字节数;
9.ref:显示了哪些字段或者常量被用来和key配合从表中查询记录出来;显示那些在index查询中被当作值使用的在其他表里的字段或者constants
10.rows:估计为返回结果集而需要扫描的行;不是最终结果集的函数,把所有的rows乘起来可估算出整个query需要检查的行数,有limit时会不准确;
11.filtered:根据条件过滤的行百分比;
12.Extra:优化程序提供的每个查询的附加信息;
2.有关输出列的完整论述:http://dev.mysql.com/doc/refman/5.6/en/explain-output.html;
3.使用EXPLAIN EXTENDED…可查看优化程序提供的其他信息:http://dev.mysql.com/doc/refman/5.6/en/explain-extended.html;

select_type列:
1.SIMPLE:简单查询,没有使用UNION和子查询;
EXPLAIN SELECT * FROM actor WHERE actor_id = 1;
2.PRIMARY:包含子查询或联合查询的query中,最外层的select查询;
3.UNION:在联合查询中第二个及其以后的select对应的类型;
EXPLAIN SELECT actor_id, last_update FROM film_actor UNION ALL SELECT actor_id, last_update FROM actor;
4.DEPENDENT UNION:子查询中的union,且为union中第二个select开始的后面所有select,同样依赖于外部查询的结果集;
EXPLAIN SELECT * FROM actor WHERE actor_id IN (SELECT actor_id FROM film_actor UNION ALL SELECT actor_id FROM film_actor);
5.UNION RESULT:从UNION临时表获取结果集合;
6.SUBQUERY:子查询在SELECT的目标里,不在FROM中,子查询中的第一个SELECT;
EXPLAIN SELECT (SELECT actor_id FROM actor) FROM film_actor;
7.DEPENDENT SUBQUERY:子查询中的第一个查询,依赖于外部查询的结果集;
8.DERIVED:子查询在from子句中,执行查询的时候会把子查询的结果集放到临时表(衍生表);
EXPLAIN SELECT * FROM (SELECT * FROM actor) AS a;
9.MATERIALIZED:物化子查询;
10.UNCACHEABLE SUBQUERY:表示子查询,但返回结果不能被cache,必须依据外层查询重新计算;
11.UNCACHEABLE UNION:表示union第二个或以后的select,但结果不能被cache,必须依据外层查询重新计算;

type列:访问路径(效率依次降低):
0.NULL:在优化过程中就已得到结果,不用再访问表或索引;
EXPLAIN SELECT * FROM actor WHERE actor_id = -1;
1.system:当表只有一行时就会出现system类型;是const join类型的特例;在没有任何索引的情况下,只有一条数据,MyISAM会显示system,InnoDB会显示ALL;
use test;
CREATE TABLE t_sys1(id INT) ENGINE = InnoDB;
CREATE TABLE t_sys2(id INT) ENGINE = MyISAM;
INSERT INTO t_sys1 VALUES(1);
COMMIT;
INSERT INTO t_sys2 VALUES(1);
EXPLAIN SELECT * FROM t_sys1;
EXPLAIN SELECT * FROM t_sys2;
2.const:最多会有一条记录匹配,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数;const表很快,因为它们只读取一次,发生在有一个unique key或者主键,并且where子句给它设定了一个比较值;
eg:EXPLAIN SELECT * FROM actor WHERE actor_id = 1;
3.eq_ref:在做关联查询中,前一个表返回的值在此表中只有一条记录对应,这是关联查询的最好选择;所以,唯一性索引(Primary or UNIQUE NOT NULL)才会出现eq_ref(非唯一性索引会出现ref),因为唯一,所以最多只返回一条记录,找到后无需继续查找,因此比ref更快;
CREATE TABLE t_eq_ref(actor_id SMALLINT(5) PRIMARY KEY);
INSERT INTO t_eq_ref VALUES(1);
COMMIT;
EXPLAIN SELECT * FROM actor, t_eq_ref WHERE actor.actor_id = t_eq_ref.actor_id;
4.ref:这是一种索引访问;只有当使用一个非唯一性索引或者唯一性索引的非唯一性前缀(换句话说,就是无法根据该值只取得一条记录)时才会发生,将索引和某个值相比较,这个值可能是一个常数,也可能是来自前一个表里的多表查询的结果值;如果使用的键仅仅匹配少量行,该联接类型是不错的;
EXPLAIN SELECT * FROM film_actor, actor WHERE film_actor.actor_id=actor.actor_id AND film_actor.actor_id = 1;
5.ref_or_null:类似ref,不同的是MySQL会在检索的时候额外的搜索包含NULL值的记录,他意味着MySQL必须进行二次查找,在初次查找的结果中找出NULL条目;
6.index_merge:查询中使用两个或多个索引,然后对索引结果进行合并;在这种情况下,key列包含所有使用的索引,key_len包含这些索引的最长的关键元素;
7.unique_subquery:用来优化有子查询的in,并且该子查询是通过一个unique key选择的,子查询返回的字段组合是主键或者唯一索引;
value IN (SELECT primary_key FROM single_table WHERE some_expr)
EXPLAIN SELECT * FROM actor WHERE actor_id IN (SELECT actor_id FROM actor);
8.index_subquery:与unique_subquery类似,子查询中的返回结果字段组合是一个索引或索引组合,但不是一个主键或者唯一索引;
value IN (SELECT key_column FROM single_table WHERE some_expr)
EXPLAIN SELECT * FROM film_actor WHERE film_id IN (SELECT film_id FROM film_actor);
9.range:使用索引扫描,只查询给定范围的记录;比如出现=, <>, >, >=, < , <=, IS NULL, <=>, BETWEEN, or IN()操作符时:
EXPLAIN SELECT * FROM actor WHERE id < 10; 10.index:按索引次序扫描数据,因为按照索引扫描所以会避免排序,但也会扫描整表数据,若随机读取开销会更大;如果extra列显示using index,说明使用的是覆盖索引(覆盖索引:包含所有满足查询需要的数据列的索引);对于InnoDB表特别有用,此时只访问索引数据即可,不用再根据主键信息获取原数据行,避免了二次查询;而MyISAM表优化效果相对InnoDB来说没有那么的明显; 11.ALL:全表扫描;一般情况下,应该添加索引来避免全表扫描;出了使用limit子句或者Extra列有distinct信息; Extra列: 1.Using index:此查询使用了覆盖索引(Covering Index),即通过索引就能返回结果,无需访问表;若没显示"Using index"表示读取了表数据; EXPLAIN SELECT id FROM City WHERE id = 1890; 2.Using where:表示MySQL服务器从存储引擎收到行后再进行“后过滤”(Post-filter);所谓“后过滤”,就是先读取整行数据,再检查此行是否符合where句的条件,符合就留下,不符合便丢弃;因为检查是在读取行后才进行的,所以称为“后过滤”; EXPLAIN SELECT id FROM City WHERE id < 10; 3.Using temporary:使用到临时表 EXPLAIN SELECT DISTINCT Continent FROM Country; 4.Using filesort:若查询所需的排序与使用的索引的排序一致,因为索引是已排序的,因此按索引的顺序读取结果返回;否则,在取得结果后,还需要按查询所需的顺序对结果进行排序,这时就会出现Using filesort; EXPLAIN SELECT id, CountryCode FROM City WHERE id < 10 ORDER BY CountryCode; latin1/utf8/gbk字符数/字节数/汉字的对应关系: latin1:1character=1byte,1汉字=2character;一个字段定义成varchar(200),可以存储100个汉字或者200个字符,占用200个字节;尤其是当字段内容是字母和汉字组成时,尽量假设字段内容都是由汉字组成,据此来设置字段长度; utf8:1character=3bytes,1汉字=1character;一个字段定义成varchar(200),则它可以存储200个汉字或者200个字母,占用600个字节; gbk:1character=2bytes,1汉字=1character一个字段定义成varchar(200),则它可以存储200个汉字或者200个字母,占用400个字节; -- EXPLAIN格式; EXPLAIN输出也提供其他格式: 1.可视化EXPLAIN:在MySQL Workbench中提供图形格式的输出; 2.EXPLAIN FORMAT=JSON: 1.JSON格式的输出;JSON(JavaScript Object Notation,JavaScript对象表示法)是一种简单的数据交换格式; 2.当要将EXPLAIN输出传递给程序以供进一步处理/分析时十分有用; mysql> EXPLAIN FORMAT=JSON SELECT * FROM City\G

— 检查服务器状态;
MySQL提供了多种查看服务器状态变量的方法:
1.在mysql提示符下:
1.STATUS;
2.SHOW STATUS;
2.在终端上:
1.mysqladmin –login-path=login-path status
2.mysqladmin -u user -p extended-status
3.对mysqladmin使用选项可提供附加功能;例如,–sleep(或-i)选项可指定在迭代之间等待的秒数,并在等待该时间后自动重新执行命令;–relative(或-r)选项显示自上次迭代后每个变量的差异,而不是变量值;
shell> mysqladmin -i 5 -r status

— 主要状态变量;
1.Created_tmp_disk_tables:显示磁盘上的内部临时表的数量;获取执行语句时服务器所创建的临时表数;如果该数值较高,则服务器已在磁盘上(而不是在内存中)创建多个临时表,从而导致查询执行较慢;
2.Handler_read_first:显示索引中第一个条目的读取次数;如果该数值较高,则服务器已执行多次完整索引扫描以完成查询请求;
3.Innodb_buffer_pool_wait_free:显示服务器等待干净页面的次数;等待InnoDB缓冲池中的页面刷新后才可以完成查询请求;如果该数值较高,则未正确设置InnoDB缓冲池的大小,因而查询性能受到影响;
4.Max_used_connections:显示自服务器启动以来的最大并发连接数;此变量提供非常有用的信息来确定服务器必须支持的并发连接数;
5.Open_tables:显示给定时间内打开的表的数量;将此变量与服务器系统变量table_cache比较,可提供有关应该为表高速缓存预留多少内存量的有用信息;如果Open_tables状态变量的值通常很低,请减小服务器系统变量table_cache的大小;如果该值很高(接近服务器系统变量table_cache的值),请增加分配给表高速缓存的内存量来缩短查询响应时间;
6.Select_full_join:显示执行表扫描而不是使用索引的联接数量;如果该值不是0,则应该仔细检查表的索引;
7.Slow_queries:显示用时比long_query_time系统变量所指定的秒数长的查询数;此状态变量取决于对long_query_time变量(默认值为10秒)设置的了解;如果Slow_queries状态变量不是0,请检查long_query_time的值和慢速查询日志,并改进所捕获的查询;
8.Sort_merge_passes:显示排序算法所执行的合并传递次数,排序操作需要内存中的缓冲区;此状态变量计算排序操作所需的经过排序缓冲区的传递次数;如果该值较高,则可能表明排序缓冲区大小不足以执行查询的一次通过排序;请考虑增大sort_buffer_size系统变量的值;
9.Threads_connected:显示当前打开的连接数;定期捕获该值可提供有关服务器何时最活跃的有用信息,使 用此变量可确定执行服务器维护的最佳时间,或者可将其作为为服务器分配更多资源的依据;
10.Uptime:显示服务器持续运行的秒数;该值可以提供有关服务器运行状况的有用信息,例如服务器需要重新启动的频率;

— 调节系统变量;
1.首先调节查询,模式和索引:
1.一个常见的误区是认为服务器变量配置是服务器调节中最重要的部分;
2.事实上,优化模式,常见查询和典型数据库的索引可获得比调节变量更多的好处;
2.针对服务器大小进行调节内存和I/O:
1.Oracle的MySQL工程师选择默认设置来适应大多数生产系统,这些系统常常要处理频繁的小事务,许多更新和少数大型慢速查询(如用于生成报告的查询);
2.然而,由于MySQL在从小型设备(如销售点系统和路由器)到具有大量内存和快速磁盘阵列的大型Web服务器等各种系统上都在使用,可能会发现,对于您的特定环境和工作负荷,可以从更改服务器的某些默认设置中获益;
3.针对应用程序配置进行调节:存储引擎设置
1.将物理RAM的70%–85%提供给InnoDB缓冲池;在仅使用InnoDB用户表的MySQL专用服务器上,可以将innodb_buffer_pool_size的值增大到占服务器总内存的较大比例(70%–85%),同时要记住操作系统的需要,如cron作业,备份,病毒扫描以及管理连接和任务;如果有几GB的RAM,则还可以通过使用多个innodb_buffer_pool_instances而获益,该设置可启用多个缓冲池,从而避免争用;
2.最小化MyISAM高速缓存和缓冲区;在不将MyISAM用作用户表的系统上,减小仅适用于MyISAM的选项的值(例如将key_buffer_size的值减小为16MB等较小值),同时要记住某些内部MySQL操作将使用MyISAM;
4.调节工作负荷类型:
1.连接数;
1.当为每个查询或每个连接的高速缓存和缓冲区设置较大的值时,会减少缓冲池的可用大小;
2.调节服务器的配置变量是一个平衡过程,需要从默认值开始,提供尽可能多的内存给缓冲池,然后调节与以下项最紧密相关的变量:调节目标,通过检查服务器状态识别出的问题以及通过查询性能模式识别出的瓶颈;
2.事务服务器:
1.在用于支持许多反复断开并重新连接的快速并发事务的服务器上,请将thread_cache_size的值设置为足够大的值,以便大多数新连接可以使用高速缓存的线程;
2.这可避免创建和断开每个连接的线程时的服务器开销;在支持多写入操作的服务器上,请提高innodb_log_file_size和innodb_log_buffer_size等日志设置,因为数据修改操作的性能在很大程度上依赖 于InnoDB日志的性能;
3.请考虑更改innodb_flush_log_at_trx_commit的值以提高每次提交的性能,但风险是:如果服务器出现故障,可能会丢失某些数据;
4.如果您的应用程序反复执行相同的查询(或多个相同的查询),请考虑启用查询高速缓 存,并根据常见查询的结果调节其大小,方法是为query_cache_type和query_cache_size设置适当的值;
3.报表服务器:在用于运行少数大型慢速查询(例如用于业务智能报表的查询)的服务器上,使用join_buffer_size和sort_buffer_size等设置增加专用于缓冲区的内存量;虽然默认服务器设置更适合事务系统,但默认的my.cnf文件包含这些变量适用于报表服务器的替代值;

— 主要服务器系统变量;
1.innodb_buffer_pool_size:定义InnoDB用于缓存表数据和索引的内存缓冲区大小;要获得最佳性能,请将此值设置为尽可能大,同时要记住值过高会导致操作系统交换页面,从而大大降低性能;如果在专用数据库服务 器上仅使用了InnoDB用户表,请考虑将此变量设置为介于物理RAM的70%到85%之间的值;
2.innodb_flush_log_at_trx_commit:定义InnoDB将日志缓冲区写入日志文件的频率,以及对日志文件执行刷新到磁盘操作的频率;此变量有三种可能的设置:
1.0:每秒将日志缓冲区写入磁盘一次;
2.1:每次提交时将日志刷新到磁盘;如果未发生提交,则每秒刷新一次;
3.2:将日志刷新到操作系统高速缓存中,并且每隔innodb_flush_log_at_timeout秒(默认为一秒)刷新到磁盘一次;
3.innodb_log_buffer_size:定义InnoDB用于写入磁盘上的日志文件的缓冲区的大小;此变量的默认值为8MB;事务超过此大小会导致InnoDB在事务提交之前将日志刷新到磁盘,从而降低性能;对于使用大量BLOB或者在更新活动中具有较大峰值的应用程序,可通过增大该值提高事务性能;
4.innodb_log_file_size:定义日志组中每个日志文件的大小;对于大型数据集上的写入密集型工作负荷,请设置此变 量以便所有日志文件的最大总大小(通过innodb_log_files_in_group设置)小于或等于缓冲池的大小;大型日志文件会减缓故障恢复,但可以通过减少检查点刷新活动来提高整体性能;
5.join_buffer_size:定义用于使用表扫描的联接的最小缓冲区大小;对于包含无法使用索引的联接的查询,请以默认值(256 KB)为起点增大该值;运行此类查询时请更改每个会话的值,以避免设置全局设置而使无需这么大值的查询浪费内存;
6.query_cache_size:定义为缓存查询结果而分配的内存量;通过使用查询高速缓存,提高针对极少更改的数据发出重复查询的应用程序的性能;作为基线,请根据重复查询的数量和所返回数据的大小将此变量设置为介于32MB和512MB之间的值,请监视高速缓存命中率以确定此变量的有效性,并根据您的观察调节其值;
7.sort_buffer_size:定义分配给需要进行排序的会话的最大内存量;如果Sort_merge_passes状态变量的值很高,请增大该值以提高ORDER BY和GROUP BY操作的性能;
8.table_open_cache:定义所有线程打开的表的数量;请设置该值以使其大于N * max_connections,其中,N是在应用程序的所有查询中所使用的最大表数量;该值过高会导致出现错误“Too many open files(打开的文件太多)”;Open_tables状态变量的值较高表示MySQL频繁打开和关闭表,因此应该增大table_open_cache;
9.thread_cache_size:义服务器应缓存以供重用的线程数;默认情况下,此变量将自动调节大小;评估Threads_created状态变量可确定是否需要更改thread_cache_size的值;

— 准备调节环境;
1.尽可能地复制生产系统;
1.要减小与正在调节的变量无关的已更改因素的影响;
2.请在停机期间对生产服务器执行调节,或者最好在复制的系统上进行调节;
2.决定调节目标:
1.每秒处理更多事务;
2.更快生成复杂报表;
3.通过并发连接的峰值提高性能;
3.选择适当的变量进行调节:缓冲区,高速缓存,日志设置;
4.为了最准确地模拟正在针对其进行调节的工作负荷,需要收集一组有代表性的语句:
1.从应用程序中选择查询和修改操作比例正确的语句序列;
2.在要优化的每天或每周期间内,使用一般查询日志从生产服务器收集实际语句;

— 练习调节;
1.查找每个变量的最佳值的基准测试:
1.mysqlslap或mysql来运行工作负荷并获取平均执行时间;
2.sql-bench来运行更一般的基准测试;
3.mysqladmin extended-status来获取工作负荷前后的状态变量的值;
4.top等操作系统工具或/proc文件系统来访问过程度量;
2.将变量设置为低于其默认值的设置;
3.进行基准测试,测量相关度量:
1.虚拟内存使用;
2.所花费的平均时间;
3.相关状态变量;
4.增大变量值并重复基准测试:如果需要,刷新状态变量;
5.将结果绘制成图:
1.查找收益的下降点和性能的高峰;
2.根据所用资源和性能之间的最佳平衡来决定最终变量值;
6.如果要针对特定变量使用多个不同值运行微调基准测试,或者如果要在很长一段时间内反复运行相同的基准测试,请考虑使用脚本语言来自动化基准测试中所使用的步骤;

— 调节示例:排序缓冲区大小;
1.本幻灯片中的示例显示了一系列针对具有繁重排序工作负荷的数据库的测试结果,其中,运行测试时更改了sort_buffer_size变量;
2.图表显示:
1.在sort_buffer_size从32KB增大到512KB时,Sort_merge_passes状态变量的值(可使用mysqladmin extended_status-r查看)急剧下降,在此之后又缓慢降低;
2.测试工作负荷所花的平均时间(可使用mysqlslap查看)在sort_buffer_size为512KB时降低,在4MB时达到极大峰值,然后在8MB时下降,最终在32MB时达到最佳性能;
3.mysqld进程的总虚拟内存(可使用top查看)在sort_buffer_size为512KB时最小,此后一直到16MB都稳步上升,在32MB时急剧上升;
3.查询的平均时间最短时,sort_buffer_size为32MB,该设置使用了大量内存,而缓冲池本来可以更好地利用这些内存;在本示例中,针对测试中所使用的工作负荷,服务器和数据库的特定组合,512KB设置可在性能和所用内存之间提供最佳平衡;

— 课后练习;

— 补充:Extra其它信息;
1.distinct:当MySQL找到第一条匹配的结果值时,就停止该值的查询,然后继续该列其他值的查询;
2.not exists:在左连接中,优化器可以通过改变原有的查询组合而使用的优化方法;当发现一个匹配的行之后,不再为前面的行继续检索,可以部分减少数据访问的次数;
3.const row not found:涉及到的表为空表,里面没有数据;
4.Full scan on NULL key:是优化器对子查询的一种优化方式,无法通过索引访问NULL值的时候会做此优化;
5.Impossible Having:Having子句总是false而不能选择任何列;例如having 1=0;
6.Impossible WHERE:Where子句总是false而不能选择任何列;例如where 1=0;
7.Impossible WHERE noticed after reading const tables:MySQL通过读取“const/system tables”,发现Where子句为false;也就是说:在where子句中false条件对应的表应该是const/system tables;这个并不是MySQL通过统计信息做出的,而是真的去实际访问一遍数据后才得出的结论;当对某个表指定了主键或者非空唯一索引上的等值条件,一个query最多只可能命中一个结果,MySQL在explain之前会优先根据这一条件查找对应记录,并用记录的实际值替换query中所有用到来自该表属性的地方;
8.No matching min/max row:没有行满足如下的查询条件;
9.no matching row in const table:对一个有join的查询,包含一个空表或者没有数据满足一个唯一索引条件;
10.No tables used:查询没有From子句,或者有一个From Dual(dual:虚拟表,是为了满足select…from…习惯)子句;
EXPLAIN SELECT VERSION()
11.Range checked for each record (index map: N):MySQL发现没有好的index,但发现如果进一步获取下一张join表的列的值后,某些index可以通过range等使用;MySQL没找到合适的可用的索引;取代的办法是,对于前一个表的每一个行连接,它会做一个检验以决定该使用哪个索引(如果有的话),并且使用这个索引来从表里取得记录;这个过程不会很快,但总比没有任何索引时做表连接来得快;
12.Select tables optimized away:当我们使用某些聚合函数来访问存在索引的某个字段时,优化器会通过索引直接一次定位到所需要的数据行完成整个查询;在使用某些聚合函数如min, max的query,直接访问存储结构(B树或者B+树)的最左侧叶子节点或者最右侧叶子节点即可,这些可以通过index解决;Select count(*) from table(不包含where等子句),MyISAM保存了记录的总数,可以直接返回结果,而Innodb需要全表扫描;Query中不能有group by操作;
13.unique row not found:对于SELECT … FROM tbl_name,没有行满足unique index或者primary key;从表中查询id不存在的一个值会显示Impossible WHERE noticed after reading const tables;
14.Using filesort:指MySQL将用外部排序而不是按照index顺序排列结果;数据较少时从内存排序,否则从磁盘排序;Explain不会显示的告诉客户端用哪种排序;
15.Using index:表示MySQL使用覆盖索引避免全表扫描,不需要再到表中进行二次查找数据;注意不要和type中的index类型混淆;
16.Using index for group-by:类似Using index,所需数据只需要读取索引,当query中有group by或distinct子句时,如果分组字段也在索引中,extra就会显示该值;
17.Using temporary:MySQL将创建一个临时表来容纳中间结果;在group by和order by的时,如果有必要的话;例如group by一个非键列,优化器会创建一个临时表,有个按照group by条件构建的unique key,然后对于每条查询结果(忽略group by),尝试insert到临时表中,如果由于unique key导致insert失败,则已有的记录就相应的updated;例如,name上没有索引,SELECT name,COUNT(*) FROM product GROUP BY name,为了排序,MySQL就需要创建临时表;此时一般还会显示using filesort;
18.Using where:表示MySQL将对storage engine提取的结果进行过滤;例如,price没有index,SELECT * FROM product WHERE price=1300.00;有许多where的条件由于包含了index中的列,在查找的时候就可以过滤,所以不是所有带where子句的查询会显示Using where;
19.Using join buffer:5.1.18版本以后才有的值;join的返回列可以从buffer中获取,与当前表join;
例如:explain select * from t1,t2 where t1.col < 10 and t2.col < 10 20.Scanned N databases:指在处理information_schema查询时,有多少目录需要扫描; EXPLAIN SELECT TABLE_NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES 21.Open_full_table:指示从information_schema查询信息时有关文件开启的优化; Skip_open_table:表信息已经获得,不需要打开; 22.Open_frm_only:只打开.frm文件; Open_trigger_only:只打开.trg文件; Open_full_table:没有优化;.frm,.myd和.myi文件都打开; 23.Using sort_union(…), Using union(…), Using intersect(…):都出现在index_merge读取类型中; 1.Using sort_union:用两个或者两个以上的key提取数据,但优化器无法确保每个key会提取到一个自然排好序的结果,所以为了排除多余的数据,需要额外的处理; 2.例如,customer的state,(lname,fname)是key,但lname不是key,SELECT COUNT(*) FROM customer WHERE (lname = ‘Jones') OR (state = ‘UT'),由于lname上面没有key,所以使用(lname,fname),使得结果可能不按照顺序,优化器需要额外的一些工作; 3.Using union:用两个或者两个以上的key提取数据,分别取得结果是已排序,通过合并就可以获得正确结果;例如,customer中的state和(lname,fname)是key,SELECT COUNT(state) FROM customer WHERE (lname = ‘Jones' AND fname='John') OR (state = ‘UT'); Using intersect:用两个或者两个以上的key提取数据,分别取得结果是已排序,通过求交就可以获得正确结果; 4.例如,customer中的state和(lname,fname)是key,SELECT COUNT(state) FROM customer WHERE (lname = ‘Jones' AND fname='John') AND (state = ‘UT'); 24.Using where with pushed condition:仅用在ndb上;MySQL Cluster用Condition Pushdown优化改善非索引字段和常量之间的直接比较;condition被pushed down到cluster的数据节点,并在所有数据节点同时估算,把不合条件的列剔除避免网络传输;