MySQL数据库再回首

前言:

数据库是程序员的数据源泉,加上近期 要开发DB可视化、性能分析的功能 从新回顾一下MySQL知识,如下是笔记;html

 

 

MySQL架构

 

 

 

 

MySQL基础理论

 

1.什么是关系型数据库?node

关系型数据库,这个关系怎么讲呢?简单来讲关系就是 经过行、列组成一张二维表 把全部数据关联、表现出来;python

列:从不一样方面描述1类实体数据的属性;mysql

行:1行=1条实体数据;linux

 

2.为何要使用数据库管理系统(DBMS)?c++

 

若是咱们的数据只是像/etc/password/这样大小的一个文件,咱们使用文本文件存储数据是彻底没有问题的;
可是使用文件的方式存储数据有下列缺陷:程序员

数据冗余web

没法简单描述数据之间的关联性(外键、多对多、1对1)在文件中实现起来困难redis

文本文件没法保存数值数据(浮点、整型)丢失精度、没法计算算法

最重要的是 当文件中数据每人剧增变得异常庞大的时候,咱们从中查找符合条件的内容将会变得异常困难;

好比:/etc/password这个文件变成100G的时候,咱们从中查找出 …^r的用户,怎么查找?。

也许你会想到使用grep/egrep命令去查找,是的我能找到没有任何问题;

可是在100G的文件中寻找符合条件的行会遇到如下问题:

grep/egrep也是程序 若是想要 查询 就须要把100G的文件载入内容,须要多大的内存?,即使有这么大的内存会产生多大IO?花销多大时间?

 

于以上内容使用一个简单的文件来存储数据,只能 在早期 知足1个简单数据模型的应用程序;

 

 

3.什么是搜素引擎?

若是1个python程序使用文件来保存数据,数据都存储在硬盘上,python和数据打交道的接口是什么?文件系统的系统调用接口;

文件存储在硬盘上,咱们经过系统调用调用到的数据都是数据流(只不过经过文件系统抽象以后才表现为文件)若是和文件数据流打交道这就意味着你的python程序就须要维护文件句柄、内容指针(读到第几行了?)、什么时候关闭文件、关闭以前清理缓冲区....管理;

 

咱们都知道文件系统把数据放在磁盘的某1个块上的,假如说这个python程序想要访问某1数据块,python也须要将这个文件的全部内容载入到内存中才能访问的;

为何是全部文件内容?因程序自己没法界定符合条件的内容到底存储在 哪一个数据块上?

因而在文件系统之上又封装了一层管理功能,这个管理工具向下能够和文件系统打交道,将N个文件系统的块 组织成1个更高级别的逻辑存储块。

划分出这些逻辑块以后,就能够知道那些数据存储在哪一个数据块上并记录下来;因此好比当咱们查询/etc/password的1-5行时就能够载入部分数据块了;由于如今已经知道了那些数据在哪一个数据块上,无需在访问部分数据时加载所有文件的数据块了;

 

可是还有1个问题 若是 咱们要查询 /etc/password 以^r开头的用户

那么就会出现1个问题即便你知道 某1行数据在哪1数据块?但也须要载入所有数据块(若是1个数据块对应1行数据)去每一个块上找1下;

因此咱们能够把一些搜素条件单独组合成搜素码,单独存储在1个数据块上,这样用户搜素的时候就能够只载入1个数据块而不是所有了!

若是 咱们要查询 /etc/password 以^r开头的用户全部信息包含家目录、登陆shell

因此咱们不只要把搜素码单独存储起来,还有存储它相关信息所在搜素块的映射关系;这就是索引

 

 

索引分级:

若是把全部搜素条件都作成搜素块(索引)那么数据库每次启动加载全部全部索引信息也是很是慢慢的,索引也须要分级;

 

数据库缓冲区:

加载索引 、常常访问的数据到内存加速用户访问速度;

 

搜素引擎:

以上内容 将数据从1个物理模型转换成数据库能理解的数据库模型、根据上层程序调用不加载所有数据块而非所有数据的 就是数据库引擎;

读锁:共享锁

写锁:独占锁

 

 

httpMPM

multi-processing  module  并发响应模型

http支持三种方式解决并发问题:

prefork:1个进程处理1个请求

worker:多个进程处理1个请求

event:1个线程处理多个请求(IO多路复用 + 协程)时间通知回调 协程切换

 

mysq并发:1个线程响应1个用户请求;

为啥不用1个线程处理多个数据库用户呢?1的用户的请求处理逻辑复杂开发难度比较大;

 

4.为何要用mysql线程池?

由于mysql的线程比较重量级,在大并发的场景下线程的建立、释放、销毁都须要必定时间,因此为了最大限度复用线程就有了进程池,用户使用完线程以后清除该用户的数据但不销毁而是把该线程回收到线程池中,留个下1个用户继续使用;

还有1点就是能够限制并发的数量;

 

5.sql语句分类

DML:对数据库数据数据的操做Insert、Update、Delete、Select

DDL:对数据库对象(表、视图、索引、存储过程、存储函数)建立、删除、修改操做;Create Drop Al

Alter

DCL:Grant、Revoke 用户受权和回收权限

 

6.事物是什么?

一组DML就是一个事物,它具备如下特性:

原子性:一组DML(多条增、删、改、查的sql语句)要么都执行,要么都不执行;(当作1个总体来管理)

一致性:事物操做数据总量保存不变A向B转帐100, A的帐户少了100,B的帐户就要加100,就这么简单;

隔离性:隔离多个事物,避免多个事物同时进行;

隔离级别

读未提交

读提交

可重读

可串行化

持久性:事物的数据一旦提交以后不能丢失,中间出现问题能够回滚;经过事物日志来保证;

 

 

7.Mysql的日志类型

错误日志

查询日志

慢查询日志

事物日志

二进制日志

中间日志

 

 

8.DBA职责

设计表结构、安全性和受权、保障数据库可用性、故障恢复、数据库调优

 

 

 

2、关系型数据库索引、数据库文件的组织方式

1.mysql的数据类型 CHAR(定长)和VARVHAR(变长)

CHAR数据类型的长度是固定的,VARCHAR数据类型的长度是可变、非固定的,

变长:VARCHAR(20)  存储root字符串占用数据库5字节空间, 优点:节省空间、其长度可变占用空间可扩展;应用在数据最大和最小长度相差太大的场景;

定长:CHAR(20)        存储root字符串占用数据库20字节空间,优点:方便搜素引擎存储、索引查找,数据最大和最小长度相差不太大的场景都要尽可能使用CHAR类型;

 

2.数据库文件

数据文件:堆文件(组织无序)、有序文件(组织有序)、散列组织(hash函数+hash桶)

索引文件:有序索引文件、无序索引文件

日志文件:存储搜素引擎的操做记录,便于追溯、恢复数据;

 

3.数据库索引

聚簇索引

搜索引擎 把数据 存储在索引上所指向数据库块位置,若是索引自己有序,数据记录也是有序的,这种索引就是聚簇索引,按这种方式组织的数据库文件也叫有序数据、聚簇文件;(有序文件+有序索引文件+存储在一块儿)

 

非聚簇索引

与相反若是索引自己无序 因而数据记录就是无序的,或者索引有序、数据记录无序 这种索引就是非聚簇索引,按这种方式组织的数据库文件也叫无序数据、堆文件;

 

非聚簇索引包含散列(hash)索引

若是散列文件组织就使用hash算法去存储和查找;注意hash算法的时间复杂度=o(1),但不适合范围查找;由于即便数据会被hash算法随机分配到不一样的hash桶里;

 

小结

索引和数据库文件结构关联性很大

 一般树状结构索引都是有序的称为聚簇索引,辅助索引、hansh索引无序称为非聚簇索引。

 

4. 两大引擎存储数据库、索引文件的特征

每张表都有3个文件;

MyISM: 数据文件=表名.MYD,索引文件=表名.MYI ,表定义文件=表名.frm

InnoDB:

每张表的全部数据都放在表空间中(ibdata),表空间能够被多个位于不一样数据库的表共享;

定义文件在数据库目录中;

 

5.MySQL数据字典

保存数据库的元数据

关系的名字

张表中各列的名字

每列的数据类型和长度

每张表上的视图名称

 

受权用户的名字

用户受权和帐户信息

以上信息存储在mysql库;

 

统计类数据

每一个库中属性的个数

每一个表中行的个数

每一个关系的存储组织方法

infomation_schema存储统计类信息;

 

Mysql安装自带如下3个库就是用来存储数据字典信息的;

mysql库:帐号受权

information_schema库:统计类信息

performance_schema 库:存储性能相关信息

总结:^_^ 有了以上自带的3个库仿佛看到了DB可视化功能的大门~~~~

import pymysql
db = pymysql.connect("172.17.10.112", "webproject", "xxxxxx1234","web")
cursor = db.cursor()
cursor.execute(" show variables like 'max_connections';") #查当前登陆用户声明的变量
cursor.execute(" show global variables")                    #查当前全局声明的变量
cursor.execute("show status like '%Threads_connected%'") #查看MySQL运行状态 https://www.cnblogs.com/zuxing/articles/7761262.html
print(cursor.fetchall())
# 关闭数据库链接
db.close()
在线查看部分信息

 

3、安装MySQL 

主要描述基于centos7 64位系统源码安装MySQL5.6.19

为啥不使用 yum安装呢?由于下载MySQL源码编译时能够指定参数定制出适合本身企业数据库

 

1.MySQL官网下载源码

Archive 存档档案文件;档案室;若是想下载以前的版本;

 

 Community Server 社区版服务端下载 

 

 

 

Archives 存档  Generic通用 Community 共同体 社区  Poor me ....So I need to learning English and take notes.

 

4、编译安装MySQL源码

1.卸载原MySQL、准备C语言编译环境

确保本机没有安装Maria或者MySQL以后再安装

rpm -qa | grep mysq
rpm -e --nodeps xx
find / -name mysql
rm -rf 
yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake make

建立MySQL用户、组

useradd -M -s /sbin/nologin mysql

建立存放MySQL源码的目录

mkdir /opt/

 

2.建立MySQL的源目录、数据存储目录并赋予权限

mkdir /usr/local/mysql/         #/usr/local/mysql/
mkdir /usr/local/mysql/data     #/usr/local/mysql/data
mkdir /usr/local/boost          #/usr/local/boost
chown -R mysql:mysql /usr/local/mysql/*

 

3.编译安装

tar -zxvf mysql-5.6.19-linux-glibc2.5-x86_64 -C /opt/
cd /opt/mysql-5.6.19-linux-glibc2.5-x86_64/
 参数说明:
    -DCMAKE_INSTALL_PREFIX=/usr/local/mysql        -----   安装目录  这是MySQL的默认安装位置,而我选择的是/u01/mysql ,我以为这样管理方便,清晰
    -DINSTALL_DATADIR=/usr/local/mysql/data        -----   数据库存放目录
    -DDEFAULT_CHARSET=utf8                      -----   使用utf8字符
    -DDEFAULT_COLLATION=utf8_general_ci            -----    校验字符
    -DEXTRA_CHARSETS=all                        -----    安装全部扩展字符集
    -DENABLED_LOCAL_INFILE=1                     -----    容许从本地导入数据
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DSYSCONFDIR=/etc -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci

编译成功以后就能够安装MySQL了;

make install  

在保证下载的是 MySQLSourceCode的状况下,哪里报错就去网上搜解决方案直到你的Linux具有编译、安装环境

 

数据库目录相关文件说明

[root@localhost data]# ls -lh
total 109M
-rw-rw----. 1 mysql mysql   56 Nov 29 17:17 auto.cnf
-rw-rw----. 1 mysql mysql  12M Nov 30 09:55 ibdata1          #innodb公共表空间文件:存储个表的数据内容和索引内容。 -rw-rw----. 1 mysql mysql  48M Nov 30 09:55 ib_logfile0      #事物日志 -rw-rw----. 1 mysql mysql  48M Nov 29 17:00 ib_logfile1      #事物日志 -rw-r-----. 1 mysql root  7.6K Nov 30 09:59 localhost.localdomain.err  #当前主机主机名+err结尾错误日志
-rw-rw----. 1 mysql mysql    7 Nov 30 09:55 localhost.localdomain.pid  #+err结尾错误日志
drwx------. 2 mysql mysql 4.0K Nov 29 17:00 mysql drwx------.  #MySQL有几个库就会有几个以数据库命名的文件

2 mysql mysql 4.0K Nov 29 17:02 performance_schema drwxr-xr-x.
2 mysql mysql 20 Nov 29 16:41 test

 

 

4.初始化数据库 启动MySQL服务

声明系统变量就能够 直接 使用mysql 命令进入数据了

export PATH=/usr/local/mysql/bin:$PATH
/etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh 
cd /usr/local/mysql
./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data #初始化数据
[mysqld]
port=3306
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock

!includedir /etc/my.cnf.d
/etc/my.conf

 

删除匿名和其余无关用户

mysql> select user,host,password from user;
+----------+-----------------------+-------------------------------------------+
| user     | host                  | password                                  |
+----------+-----------------------+-------------------------------------------+
| root     | localhost             | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
| root     | localhost.localdomain |                                           |
| root | 127.0.0.1             |                                           |
| root     | ::1                   |                                           |
| zhanggen | %.%.%.%               | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
| zhenggen | %.%.%.%               |                                           |
| zhanggen | %                     | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
| martin   | %                     | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
+----------+-----------------------+-------------------------------------------+
8 rows in set (0.01 sec)
mysql> delete from mysql.user where user='';
Query OK, 0 rows affected (0.03 sec)
mysql> drop user root@'::1';

 

 

启动MySQL

[root@localhost zhanggen]# /usr/local/mysql/support-files/mysql.server restart
Shutting down MySQL... SUCCESS! 
Starting MySQL... SUCCESS! 

 进入MySQL

[root@localhost /]# /usr/local/mysql/bin/mysql mysql

 

5.设置建立开发用户设置密码并受权

修改root密码

mysql> set password for root@localhost = password('123'); 
Query OK, 0 rows affected (0.00 sec)

增长开发用户并受权

mysql>  create user 'martin'@'%' identified by '123.com';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all privileges  on *.* to 'martin'@'%';    
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

 

6.MySQL忘记root密码怎么办?

在配置文件中追加2行参数:

skip-grant-tables   #运行本机无密码访问
skip-networking     #不容许经过scoket访问,注意一点要加上不然能够从外网无密码链接数据库;

 

7.python自动化批量源码安装脚本

须要稍加改造~

import paramiko
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh._policy = paramiko.AutoAddPolicy()
# print(host,port,username,password)
ssh.connect(hostname='192.168.226.139',port=22, username='root', password='123.com')
stdin,stdout,stderr = ssh.exec_command('rpm -qa | grep mysql')
result = stdout.read().decode('utf-8')

mysql_rpm_list=result.split('\n')
if mysql_rpm_list:
    for rpm in mysql_rpm_list:
        ssh.exec_command('rpm -e --nodeps %s' % (rpm))

stdin,stdout,stderr=ssh.exec_command('find / -name mysql')
result = stdout.read().decode('utf-8')
mysql_path_list=result.split('\n')
if mysql_path_list:
    for path in mysql_path_list:
        ssh.exec_command('rm -rf %s'%(path))

ssh.exec_command('yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake make')
ssh.exec_command('useradd -M -s /sbin/nologin mysql') # //建立用户mysql,不建立家目录,不容许登录系统
ssh.exec_command('mkdir /opt/')
ssh.exec_command('mkdir /usr/local/mysql/ ') #/usr/local/mysql/
ssh.exec_command('mkdir /usr/local/mysql/data ')  #/usr/local/mysql/data
ssh.exec_command('mkdir /usr/local/boost')        #/usr/local/boost
ssh.exec_command('chown -R mysql:mysql /usr/local/mysql/*')
# transport = paramiko.Transport(('192.168.226.139', 22))
# transport.connect(username='root', password='123.com')
# sftp = paramiko.SFTPClient.from_transport(transport)
# sftp.put('/opt/mysql-5.6.19-linux-glibc2.5-x86_64', '/opt/mysql-5.6.19-linux-glibc2.5-x86_64')
ssh.exec_command('cd /opt/mysql-5.6.19-linux-glibc2.5-x86_64/')
make='cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DSYSCONFDIR=/etc -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci'
ssh.exec_command(make)
ssh.exec_command('make install')
ssh.exec_command('cd /usr/local/mysql')
ssh.exec_command('./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data')
#vim /etc/my.conf  [mysqld]
'''
port=3306
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock

'''

#cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
#basedir='/usr/local/mysql/'  datadir='/usr/local/mysql/data'
#/etc/init.d/mysqld start
ssh.close()


import pymysql
db = pymysql.connect("192.168.226.139", "martin", "123.com","mysql")
cursor = db.cursor()
cursor.execute(" show variables like 'max_connections';") #查当前登陆用户声明的变量
cursor.execute(" show global variables")                    #查当前全局声明的变量
cursor.execute("show status like '%Threads_connected%'") #查看MySQL运行状态 https://www.cnblogs.com/zuxing/articles/7761262.html
print(cursor.fetchall())
# 关闭数据库链接
db.close()
python源码安装mysql

 

 

5、MySQL的变量

 无论是show variables 仍是 show status 都区分全局仍是会话级别;

session级别:会话级别的全部设置仅仅对当前会话生效,该会话结束会复原;

mysql> set default_storage_engine=myisam;
Query OK, 0 rows affected (0.08 sec)

mysql> show global variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | InnoDB |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | InnoDB |
+----------------------------+--------+
3 rows in set (0.01 sec)

mysql> show variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | MyISAM |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | MyISAM |
+----------------------------+--------+

 

global级别:全局级别全部设置对全部会话生效,可是须要有root权限、对当前会话无效,退出该会话才能生效,MySQL重启以后复原;

mysql> set global default_storage_engine=innodb;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | MyISAM |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | MyISAM |
+----------------------------+--------+
3 rows in set (0.00 sec)

 

 

 查看

mysql> show variables like '%variables_name%';
mysql> select @@variables_name;

设置

set variables_name=value;
set global variables_name=value

 

 

1. 系统变量 show variables

MySQL内部声明了443个系统变量,经过show variables;查看 经过set 这些变量对MySQL的性能进行优化;

innodb_adaptive_flushing={ON|OFF}

设定是否容许MySQL服务器根据工做负载动态调整刷写InnoDB buffer pool中的脏页的速率。动态调整刷写速率的目的在于避免出现IO活动尖峰。默认值为ON。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_adaptive_hash_index={ON|OFF}
设定是否启用InnoDB的自适应hash索引。基准测试结果显示,自适应hash索引并不是对全部工做负载都有益,所以须要根据实际应用场景的测试结果选择更合适的值。此特性默认已启用,能够经过命令行选项--skip-innodb_adaptive_hash_index将其禁用。做用范围是全局,可用于选项文件,属动态变量。
 
innodb_additional_mem_pool_size={2097152 .. 4294967295}
设定innodb存储引擎为了存储数据字典和其它内部数据结构的内在池大小,单位是字节。表的个数越多,此参数的值就应该设定的越大;当InnoDB用完此内存池的空间,它就会向操做系统申请内存空间,并将向错误日志记录警告信息。默认大小是8MB。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_autoextend_increment={1 .. 1000}
当共享表空间没有多余的存储空间时,若是其容许自动增加,此变量可用于设定其单次增加的空间大小,单位是MB,默认值是8。设置了变量innodb_file_per_table的值为1时InnoDB会为每张表使用一个单独的表空间文件,而innodb_autoextend_increment变量不会对此种表空间产生影响。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_autoinc_lock_mode={0|1|2}
设定用于生成“自动增加(auto_increment字段)”值的锁模型。其可接受的值有0、1和2,分别用于表示"traditional"、"consecutive"和"interleaved"锁模型。默认值为1。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_buffer_pool_instances=#
设定将InnoDB的buffer pool分隔为多少个区域。对于有着数GB空间的buffer pool来讲,将其分隔为多个区域能够下降不一样的线程对缓存页面的读写操做时资源争用系数,进行加强其并发能力。在buffer pool中,读取或存入页面时所选择的区域是基于hash算法随机进行的。每一个buffer pool管理本身的空闲列表、列表刷写、LRU以及其它跟buffer pool相关的数据结构,并经过各自的互斥锁进行保护。
此变量仅在变量innodb_buffer_pool_size的值大于1G时才能发挥功用,缓冲池的总体空间将由各buffer pool实例分割使用。出于最佳效用的目的,建议配合使用innodb_buffer_pool_instances和innodb_buffer_pool_size变量以使得每一个buffer pool实例的都至少有1G的空间。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_buffer_pool_size=#
设定InnoDB缓存表数据和索引的内存缓冲区大小,单位是字节。其默认值为128MB,最大值依赖于CPU架构。在一个较繁忙的服务器上,当缓冲池(buffer pool)大于1G时,设定innodb_buffer_pool_instances的值大于1可提其升伸缩能力。innodb_buffer_pool_size变量的值越大,MySQL服务器完成数据访问时就须要越少的IO,所以,在一个有够较大内存且为MySQL服务专用的服务器上,能够将此值设置为物理内存的80%。但若是出现以下状况,建议缩小此变量的值:(1)物理内存资源紧张致使内存页面换出;(2)InnoDB会为缓冲和控制结构(buffers and control structures)预留额外的内存,所以事实上其占用的内存空间可能会比指定的数值大10%左右,这不可能超出对内存资源分配的预估;(3)内存地址空间必须连续,这在基于DLL库使用特殊地址空间的Windows系统上可能会出现意外状况;(4)缓冲池的初始化所须要时长与为其指定的空间大小成正比,例若有10G缓冲池的x86_64的Linux系统上,初始化时间大约要6秒钟。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_change_buffering=#
当在表上执行INSERT、UPDATE或DELETE操做时,索引中尤为是第二索引中的数据未必按序存储,这就可能引起随机IO以完成第二索引的更新操做。此变量用来设定InnoDB是否启用修改缓冲(change buffering)以及使用何种类型的修改缓冲。修改缓冲是一种优化方式,它可以经过延迟写入操做至第二索引将IO操做转换为顺序模式。其接受的值有inserts(缓冲insert操做)、deletes(缓冲delete-marking操做)、changes(缓冲insert和delete-marking操做)、purges(缓冲purge操做)、all(缓冲insert、delete-marking和purge操做)和none(不缓冲任何操做)。默认值是all。MySQL 5.5.4以前的版本只接受inserts和none两种值。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_checksums={ON|OFF}
InnoDB可以使用校验和(checksum)来验正从磁盘读取的全部页面数据的完整性,从而提升对硬件或数据文件损坏的容错能力。默认为启用,然而,在少数状况下或许须要禁用这种特性,这能够经过使用--skip-innodb-checksums命令行选项实现。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_commit_concurrency={0 .. 1000}
设定InnoDB可同时运行的“提交”操做线程的数量。0表示无限制。此变量不能在运行时将其从“零值”修改成“非零值”,但能够从一个“非零值”修改成其它值。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_concurrency_tickets=#
在一个线程进入(enter)InnoDB时,其将会获取必定数量的“自由卷轴”(free tickets)并凭这些卷轴自由出入InnoDB(即免检),直到其卷轴耗尽;然后的线程将被置于等待队列中,并可能须要再次接受并发上限限制检查。此变量则正是用于设定可同时进入InnoDB的线程并发数,即线程的“自由卷轴”数量。默认值是500。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_data_file_path=IBDATA_FILE
指定InnoDB的各个数据文件及其大小,文件多于一个时彼此间用分号隔开。数据文件路径能够为相对路径,其相对于innodb_data_home_dir变量所指向的目录;而文件大小的表示能够以K(KB)、M(MB)、G(GB)为单位,但这些文件的大小之和至少要达到10MB。在没有显式设定innodb_data_file_path变量的状况下,MySQL服务器会在数据目录中自动建立一个可自动增加、初始大小为10MB的名为ibdata1的数据文件。单个数据文件的大小上限取决于操做系统,这意味着可使用操做系统所支持的最大单个文件大小觉得其数据文件的体积上限。InnoDB还支持使用裸设备做为数据文件。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_data_home_dir=/PATH/TO/DIR
InnoDB全部共享表空间数据文件的目录路径。默认值为MySQL的数据目录。能够将此变量的值设置为空,而后在innodb_data_file_path中为每一个数据文件使用绝对路径。此变量不影响变量innodb_file_per_table启用状态下的每表表空间的数据文件。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_doublewirte={ON|OFF}
设定InnoDB是否使用双写缓冲。默认为启用。InnoDB在对页面进行部分写入的时候使用双写缓冲,以防止数据损坏。双写缓冲是表空间中一个特殊的保留区域,其大小足够在一个连续区间容纳100个页面。当InnoDB把页面从缓冲池刷写至磁盘时,它会先把这些页面刷到双写缓冲中,而后再保存至真正的目标位置。所以,双写缓冲本质上是最近写入页面的备份,其可确保每次写入的原子性和可持续性。在有些状况下双写缓冲是没必要要的,例如在从服务器上就能够将之禁用;此外,一些文件系统(如ZFS)自身也会实现此功能,那么InnoDB就不用作重复的工做了。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_fast_shutdown={0|1|2}
设定InnoDB关闭模式。其可接受的值中,“0”表示慢速关闭,这意味着InnoDB关闭以前会完成彻底清写(full purge)和修改缓冲合并(insert buffer merge)操做;“1”是默认值,它表示InnoDB在关闭时会跳过模式0中进行的这些操做,这也是其之因此称做“快速关闭”的缘由;“2”表示InnoDB仅刷写日志信息并执行冷(cold)关闭,此时并无事务丢失,只是下次启动MySQL服务时须要花费较长的时间进行故障恢复(crash recovery)。
执行慢速关闭时其过程可能会持续数分钟的时间,甚至在有些极端状况下,好比有着大量数据缓冲的场景,此过程时长会以小时来计。通常状况下仅在对MySQL进行主版本升级时才须要进行慢速关闭以使得数据文件可以为彻底适应新版本而准备稳当。一般也只能遇到紧急情况或出于调试的目的才须要将此变量的值设定为2,以便让处于有可能损坏风险中的数据执行最快速度的关闭。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_file_format={Antelope|Barracuda}
设定新建InnoDB表的文件格式。其可接受的参数有Antelope和Barracuda,但这仅对基于变量innodb_file_per_file的每表表空间文件有影响。某些InnoDB特性如表压缩功能仅有Barracuda文件格式支持。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_file_format_check={ON|OFF}
用于设定InnoDB是否在MySQL服务器启动时检查共享表空间的文件格式标签。检查标签时若是其高于当前InnoDB版本所支持的能力,InnoDB就会产生错误并拒绝启动;不然,对MySQL 5.5.5 及后来的版原本说InnoDB则会设置变量innodb_file_format_max的值为共享表空间的文件格式标签,而对于MySQL 5.5.5以前的版原本说,InnoDB会将共享表空间的文件格式设置为变量innodb_file_format_check的值。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_file_format_max={Antelope|Barracuda}
在MySQL服务启动时,InnoDB会将变量innodb_file_format_max的值设置为共享表空间的文件格式标签(好比,Antelope或Barracuda)。若是MySQL服务器建立或打开了一个有着更高级格式的表,此变量的值则会被设置为那个更高级的格式。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_file_per_table={ON|OFF}
设定InnoDB表是否使用每表表空间数据文件(以.ibd结尾)分别存储每一个表的数据和索引。若是使用了每表表空间数据文件,其将再也不使用系统表空间(即共享表空间)。InnoDB表的某些特性,如压缩表等仅对每表表空间生效。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_flush_log_at_trx_commit={0|1|2}
设定InnoDB同步日志缓冲区(log buffer)数据至日志文件中的方式,以及刷写日志文件至磁盘的方式。其可接受的值中,“0”表示将日志缓冲区每秒一次地写入日志文件,并同时将日志文件刷写至磁盘中,但事务提交时不会采起任何动做;“1”是默认值,表示在有事务提交时将日志缓冲区写入日志文件,并同时将日志文件刷写至磁盘;“2”表示每事务提交或每秒一次将日志缓冲区写入日志文件,但不会同时执行日志文件的刷写操做。固然,因为操做系统进程调度的缘由,每秒一次的日志写入或刷写操做并不能获得100%的保证。
彻底兼容ACID的场景须要将此变量值设置为1,因为要执行每事务的日志刷写操做,其会阻止I/O调用,直到写操做完成,故其会显著下降InnoDB每秒钟能够提交的事务数。设置为“2”可得到比“1”更好的性能,并且仅在操做系统崩溃时才会丢失最后一秒钟的数据,所以数据安全性也有着不错的表现。设置为“0”则有可能会致使事务最后一秒钟的数据丢失,因而整个事务的数据安全性将没法保证,但其一般有着最好的性能。为了在最大程序上保证复制的InnoDB事务持久性和一致性,应该设置变量innodb_flush_log_at_trx_commit=1以及设置变量sync_binlog=1。
然而须要注意的是,有些磁盘自身也有缓存,这可能会给事务操做带来额外的潜在风险。可使用hdparm工具或供应商的自有工具等禁用磁盘自身的缓存。固然,高性能事务的最佳配置是把此变量的值设置为1,而且将日志文件放在有备用电池的写入缓存的RAID上。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_flush_method={O_DSYNC|O_DIRECT}
设定InnoDB实际与文件系统进行交互的方式。除了写操做以外,它还能够影响InnoDB如何读取数据。设置innodb_flush_method变量的值为O_DSYNC时,InnoDB使用O_SYNC标志来打开和刷写日志文件,而使用fsync()来刷写数据文件。O_SYNC会使得全部的写入操做都是同步的,即只有在数据被写入磁盘以后才会返回,但不会在操做系统层面禁止缓存,所以,它不会避免双缓冲,而且不会直接写入磁盘。fsync()会同时刷数据和元数据(而fdatasync()只刷写数据),它比fdatasync()产生更多的IO操做,并且操做系统会缓存一些数据在本身的缓存中(这将致使双缓冲)。如文件系统能够智能地处理I/O需求,双缓冲可能不是坏事儿,但若是MySQL设置了innodb_file_per_table变量的值为1,则会致使第个表空间文件都单独使用fsync()函数,其写入操做就不可能会被合并了。
设置innodb_flush_method变量的值为O_DIRECT时,InnoDB使用O_DIRECT标志打开数据文件,而使用fsync()刷写数据和日志文件。O_DIRECT标志会致使操做系统既不缓存数据,也不预读数据,它彻底禁止了操做系统的缓存而且使全部的读写动做直接至存储设备,避免了双缓冲。然而,其不能禁止硬件层面(如RAID卡)的缓存和预读功能,并且启用硬件层面的缓存和预读功能也是保证InnoDB使用了O_DIRECT标志时仍能保持良好性能的唯一途径。
做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_force_load_corrupted={ON|OFF}
设定InnoDB在启动时是否装载标记为“已损坏(corrupted)”的表。仅应该在troubleshooting的场景中启用该功能以修复没法访问的表,在troubleshooting任务完成后应该禁用此功能并重启MySQL服务。做用范围为全局,可用于选项文件,属非动态变量。
 
innodb_force_recovery={0|1|2|3|4|5|6}
设定InnoDB的故障恢复模式。InnoDB出现了“页面损坏(page corruption)”时,一般大部分数据仍然无缺,因而能够经过SELECT...INTO OUTFILE命令备份出数据以下降损失程度。然而,某些“损坏”类的故障可能会致使SELECT * FROM tbl_name命令没法执行或InnoDB后台操做崩溃,甚至会致使InnoDB的前滚操做。这种状况下,就可使用innodb_force_recovery变量强制InnoDB存储引擎在启动时不执行后台操做,以便能将数据备份出来。
innodb_force_recovery可接受的值中,“0”为默认值,表示执行正常启动,即不启用“强制修复”模式。而非零值中,某数值会包含比其小的全部数值的预防措施,然而其也较可能给B-tree索引及其它的数据结构带来更多的损坏。故此,在此变量值为非零值时,其会阻止用户使用INSERT、UPDATE或DELETE操做,可是会容许执行SELECT、CREATE TABLE或DROP TABLE类的操做。如下是关于其它非零值功能的说明:
1(SRV_FORCE_IGNORE_CORRUPT):即便出现了页面损坏也照常运行MySQL服务,其会在SELECT * FROM tbl_name语句执行时尝试跳过损坏的索引记录和页面。
2(SRV_FORCE_NO_BACKGROUND):禁止启动主线程(master thread),其会在执行清写(purge)操做时防止出现崩溃(crash)。
3(SRV_FORCE_NO_TRX_UNDO):在故障恢复(crash recovery)后不执行事务的回滚操做。
4(SRV_FORCE_NO_IBUF_MERGE):禁止执行修改缓冲(insert buffer)合并操做。
5(SRV_FORCE_NO_UNDO_LOG_SCAN):在启动数据库服务时不检查撤消日志(undo logs),这会致使InnoDB将未完成的事务视为已提交。
6(SRV_FORCE_NO_LOG_REDO):不执行重作日志(redo log)的前滚操做。此时,仅能执行不带WHERE、ORDER BY或其它子句的SELECT * FROM tbl_name操做,由于复杂查询在遇到损坏的数据结构时会停止并退出。
 
innodb_io_capacity=#
设定InnoDB后台任务(如从缓冲池刷写页面或合并修改缓冲中的数据等)可执行的I/O操做上限。其最小值为100,默认值为200,最大值取决于CPU架构。对于有着较大I/O负载的服务器来说,应该为其指定更大的值以便可以更好更快的执行后台维护任务。然而,在实践中,此变量的值应该尽量接近MySQL服务器每秒钟执行的I/O操做数量(即IOPS),甚至于让其低至以不影响后台任务执行为目标的最低限度。由于,若是此值太高的话,数据会被频繁地从缓冲中移入移出,这会下降缓存池的在系统性能提高方面的效用。单个5400RPM或7200RPM磁盘仅能完成大约100个IOPS,所以,此种状况下应该将此变量值下降至100;而对于有着多块磁盘或更强性能的存储设备(如固态磁盘)的应用场景,能够按需提升此变量的值。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_large_prefix={ON|OFF}
设定对于使用了DYNAMIC或COMPRESSED行格式的InnoDB表来讲,是否可以使用大于767字节长度的索引前缀。然而,建立此种类型的表还须要设定innodb_file_format的值为barracuda,以及innodb_file_per_table的值为ture。同时,此设定对使用了REDUNDANT和COMPACT行格式的表的索引长度限定来讲是不起做用的。做用范围为全局,可用于选项文件,属动态变量。
 
innodb_lock_wait_timeout={1 .. 1073741824}
设定InnoDB中某事务试图访问一个由其它InnoDB事务加锁的行时其最长的等待时间,单位为秒钟,默认值为50。在超时状况发生时,InnoDB会返回一个1205类型的错误信息,并对当前语句(非整个事务)执行回滚操做;若是须要在此种状况下对整个事务进行回滚,则须要在MySQL服务启动时使用--innodb_rollback_on_timeout选项。
对于OLTP系统或有着较多交互式应用的程序来讲,应该下降此变量值以使得用户较快地获取到反馈信息,或使得系统较块地将此更新操做提交到队列中以便延后处理。对于批处理应用较多的场景来讲,如数据仓库,应该增长此变量的值以等待其它较大的插入或更新操做完成。
此变量仅对InnoDB的行锁产生做用,MySQL的表锁并不是在InnoDB中实现,因此此超时时长对表锁没有影响。并且,因为InnoDB会能当即探测到死锁的发生并会对其中的一修整务执行回滚操做,所以此超时时长也不该用于死锁。做用范围为全局或会话级别,可用于选项文件,属动态变量。
 
innodb_locks_unsafe_for_binlog={ON|OFF}
设定InnnoDB是否在搜索和索引扫描中使用间隙锁(gap locking)。InnoDB使用行级锁(row-level locking),一般状况下,InnoDB在搜索或扫描索引的行锁机制中使用“下一键锁定(next-key locking)”算法来锁定某索引记录及其前部的间隙(gap),以阻塞其它用户紧跟在该索引记录以前插入其它索引记录。站在这个角度来讲,行级锁也叫索引记录锁(index-record lock)。
默认状况下,此变量的值为OFF,意为禁止使用非安全锁,也即启用间隙锁功能。将其设定为ON表示禁止锁定索引记录前的间隙,也即禁用间隙锁,InnoDB仅使用索引记录锁(index-record lock)进行索引搜索或扫描,不过,这并不由止InnoDB在执行外键约束检查或重复键检查时使用间隙锁。
启用innodb_locks_unsafe_for_binlog的效果相似于将MySQL的事务隔离级别设定为READ-COMMITTED,但两者并不彻底等同:innodb_locks_unsafe_for_binlog是全局级别的设定且只能在服务启动时设定,而事务隔离级别可全局设定并由会话级别继承,然而会话级别也以按需在运行时对其进行调整。相似READ-COMMITTED事务隔离级别,启用innodb_locks_unsafe_for_binlog也会带来“幻影问题(phantom problem)”,但除此以外,它还能带来以下特性:
(1)对UPDATE或DELETE语句来讲,InnoDB仅锁定须要更新或删除的行,对不可以被WHERE条件匹配的行施加的锁会在条件检查后予以释放。这能够有效地下降死锁出现的几率;
(2)执行UPDATE语句时,若是某行已经被其它语句锁定,InnoDB会启动一个“半一致性(semi-consistent)”读操做从MySQL最近一次提交版本中得到此行,并以之断定其是否可以并当前UPDATE的WHERE条件所匹配。若是可以匹配,MySQL会再次对其进行锁定,而若是仍有其它锁存在,则须要先等待它们退出。
 
innodb_log_buffer_size={262144 .. 4294967295}
设定InnoDB用于辅助完成日志文件写操做的日志缓冲区大小,单位是字节,默认为8MB。较大的事务能够借助于更大的日志缓冲区来避免在事务完成以前将日志缓冲区的数据写入日志文件,以减小I/O操做进而提高系统性能。所以,在有着较大事务的应用场景中,建议为此变量设定一个更大的值。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_log_file_size={108576 .. 4294967295}
设定日志组中每一个日志文件的大小,单位是字节,默认值是5MB。较为明智的取值范围是从1MB到缓存池体积的1/n,其中n表示日志组中日志文件的个数。日志文件越大,在缓存池中须要执行的检查点刷写操做就越少,这意味着所需的I/O操做也就越少,然而这也会致使较慢的故障恢复速度。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_log_files_in_group={2 .. 100}
设定日志组中日志文件的个数。InnoDB以循环的方式使用这些日志文件。默认值为2。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_log_group_home_dir=/PATH/TO/DIR
设定InnoDB重作日志文件的存储目录。在缺省使用InnoDB日志相关的全部变量时,其默认会在数据目录中建立两个大小为5MB的名为ib_logfile0和ib_logfile1的日志文件。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_max_dirty_pages_pct={0 .. 99}
设定InnoDB的缓冲池中脏页比例的上限,默认为75。当缓存池中的脏页比例接近或达到此变量定义的比值时,InnoDB的主线程会将刷写部分脏页中的数据至对应的文件中。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_max_purge_lag={0 .. 4294967295}
InnoDB事务系统会维持一个有索引记录被添加了删除标记(delete-marked)的事务的列表,此列表的长度即为清写延迟(purge_lag)。此变量用于设定当发生清写延迟时,其队列长度达到多大时开始延迟INSERT、UPDATE或DELETE操做。当puge_lag超过innodb_max_purge_lag时,将延迟这些操做((purge_lag/innodb_max_purge_lag)*10)-5毫秒。默认值为0,表示从不延迟这些操做。须要进行操做延迟与否是在purge操做刚开始时计算的,而且每隔10秒钟会从新计算一次。基于历史地缘由,purge操做没法启动时是不会有任何操做延迟的状况发生。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_mirrored_log_groups=#
设定日志组镜像的个数。其值应该为1。
 
innodb_old_blocks_pct={5 .. 95}
InnoDB以“列表”结构管理缓存池,并使用修改版的LRU算法对其执行维护操做。当须要空间以保存新块(new block)时,InnoDB会清理最近最少使用的块并将新块加入到列表中。“中点插入策略(midpoint insertion policy)”将整个列表看做两个子列表:在列表首部是那些最近被访问过的新块(new/young block)子列表,尾部是那些最近较少被访问到的旧块(lod block)子列表。而LRU算法和中点插入策略用于保证将最近常常被访问到的块置于新块子列表,InnoDB新读入的块将被置于旧块子列表的前头,并根据须要将旧块子列表中的块移除。而某个被再次访问到的旧块则会被移至新块子列表的首部。表扫描操做可能会一次性地向缓存池中读入大量的数据块并可能致使一大批旧块被移出。
此变量正是用于设置被视做旧块子列表的长度所占据整个列表长度的比例,默认值是37,即缓存池的八分之三。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_old_blocks_time=#
用于设定缓冲池中旧块子列表中的某旧块在其第一次又被访问到时,其至少须要在旧块子列表中再呆上多长时间(单位为毫秒)才会被转移至新块子列表。默认值是0,表示当即转移至新块子列表,哪怕其刚刚被转移至旧块子列表。而非零值则明肯定义旧块列表中的块在其第一次被访问到时至少须要在旧块子列表中等待转移的时长。此变量一般要结合innodb_old_blocks_pct使用。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_open_files=#
设定MySQL可同时打开的.ibd表空间文件的数量上限。此变量仅在使用多表空间文件时生效,其最小值为10,默认值为300。此变量的限定仅应用于InnoDB表的.ibd文件,跟MySQL服务器选项--open-files-limit没有关系,更不会影响表缓存的操做。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_purge_batch_size={1 .. 5000}
清写(purge)是指将缓存池中的脏页同步至持久性存储设备中的操做,以重作日志的记录为单位。此变量则用于定义清写操做的粒度,即多少个重作日志记录组合起来能够触发一次清写操做,默认值为20。此变量一般用于跟innodb_purge_threads=1一块儿对进行性能调优,但通常场景中都不须要修改它。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_purge_threads={0|1}
设定InnoDB执行清写操做的线程数量。默认值为0,表示清写操做由InnoDB的主线程本身完成,这能够下降内部资源竞争发生的几率,进而加强MySQL服务伸缩能力。不过,随着InnoDB内部各式各样的竞争愈来愈多,这种设置带来的性能优点已几乎不值一提。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_read_ahead_threshold={0 .. 64}
设定InnoDB预读页面至缓冲池时的线性预读敏感度,也即InnoDB的读操做至少从一个盘区(extent,包含64个页面)中读取多个页面时才会为读取整个盘区中后续的页面初始化一个异步读操做。默认值为56。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_read_io_threads={1 .. 64}
设定InnoDB为读操做启动的I/O线程数量,默认为4个。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_replication_delay={0 .. 4294967295}
设定在从服务器(slave)上运行的线程数达到innodb_thread_concurrency变量定义的并发上限时复制线程须要延迟的时长。默认为0,表示不延迟。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_rollback_on_timeout={ON|OFF}
设定事务执行过程超时时事务回滚的方式。在MySQL 5.5中,默认为OFF,表示仅回滚事务中的最后一个语句。若是设置为ON,则表示停止事务执行并回滚整个事务。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_rollback_segments={1 .. 128}
设定InnoDB在系统表空间中为每一个事务使用多少个回滚段(rollback segment),默认为128个。若是较少的回滚段能够提高系统性能,则应该下降此变量的值。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_spin_wait_delay={0 .. 4294967295}
自旋(spin)是一种经过不间断地测试来查看一个资源是否变为可用状态的等待操做,用于仅须要等待很短的时间等待所需资源的场景。使用自旋这种“空闲循环(busy-loop)”来完成资源等待的方式要比经过上下文切换使线程转入睡眠状态的方式要高效得多。但若是自旋了一个很短的时间后其依然没法获取资源,则仍然会转入前述第二种资源等待方式。此变量则正是用于定义InnoDB自旋操做的空闲循环转数,默认为6转。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_stats_method={nulls_equal|nulls_unequal|null_ignored}
设定MySQL为InnoDB表收集分布的索引值的统计数据时如何处理NULL类型的数据。其可接受的值有三个,null_equals意指将全部的NULL值视为相同,并为之建立一个值组(value group)以保存NULL类值的个数;nulls_unequal意指将全部的NULL值视为不一样,并为每一个NULL单首创建一个大小为1的值组;nulls_ignored表示全部的NULL值都被忽略。这些用于生成表统计数据的方法会影响到优化器为执行查询如何选择选择索引。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_stats_on_metadata={OFF|ON}
设定使用SHOW TABLE STATUS或者SHOW INDEX这两个元数据语句时,或访问INFORMATION_SCHEMA中的TABLES或STATISTICS表时,InnoDB是否更新统计数据。默认为更新。禁用此功能能够加速访问有着大量的表或索引的数据库,也可能提高InnoDB表上查询操做执行计划(execution plan)的稳定性。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_strict_mod={ON|OFF}
为防止无视SQL语句书写或语法中的错误或无视操做模式与SQL语句各类组合中的无意之过,InnoDB提供了所谓的严格模式。严格模式中,前述的问题一旦出现将会致使InnoDB产生一个错误,而非警告和一系列特定的处理操做。此参数则正是用于定义是否启用InnoDB的严格模式,默认为OFF。
 
innodb_support_xa={TRUE|FLASE}
存储引擎事务在存储引擎内部被赋予了ACID属性,分布式(XA)事务是一种高层次的事务,它利用“准备”而后“提交”(prepare-then-commit)两段式的方式将ACID属性扩展到存储引擎外部,甚至是数据库外部。然而,“准备”阶段会致使额外的磁盘刷写操做。XA须要事务协调员,它会通知全部的参与者准备提交事务(阶段1)。当协调员从全部参与者那里收到“就绪”信息时,它会指示全部参与者进行真正的“提交”操做。
此变量正是用于定义InnoDB是否支持两段式提交的分布式事务,默认为启用。事实上,全部启用了二进制日志的并支持多个线程同时向二进制日志写入数据的MySQL服务器都须要启用分布式事务,不然,多个线程对二进制日志的写入操做可能会以与原始次序不一样的方式完成,这将会在基于二进制日志的恢复操做中或者是从服务器上建立出不一样原始数据的结果。所以,除了仅有一个线程能够改变数据之外的其它应用场景都不该该禁用此功能。而在仅有一个线程能够修改数据的应用中,禁用此功能是安全的并能够提高InnoDB表的性能。做用范围为全局和会话级别,可用于选项文件,属动态变量。
 
innodb_sync_spin_loops={0 .. 4294967295}
设定一个线程在等待InnoDB释放某个互斥量(mutex)以前自旋的转数,当自旋操做达到这个转数但互斥量仍未被释放时此线程将被挂起。默认值为30。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_table_locks={ON|OFF}
InnoDB在存储引擎级别支持行级锁,而MySQL在服务器级别还支持使用表级锁。此变量则正是用来定义InnoDB是否在其内部支持使用MySQL表级锁。默认值为1或ON,表示若是autocommit变量的值为0(即禁止自动提交),在InnoDB表上显式使用LOCK TABLES语句将使得InnoDB在存储引擎内部锁定此表。使用0或OFF值,则意味着显式使用LOCKS TABLE...WRITE语句不会在存储引擎级别产生影响,但对其它显式使用的LOCK TABLES...WRITE或LOCK TABLES...READ语句依然会有影响。做用范围为全局和会话级别,可用于选项文件,属动态变量。
 
innodb_thread_concurrency={0...1000}
设定InnoDB可在其内部并发运行的操做系统线程数量上限。多出的线程将被放置于FIFO队列进行等待,且不被计入并发运行线程数量。对于不用的应用场景来讲,其理想的取值取决于硬件环境和工做负载,通常推荐为CPU个数的2倍加上磁盘的个数。默认值为0,表示无上限(不检查并发数量),这意味着InnoDB能够按须要使用任意数量的并发线程,并会禁用SHOW ENGINE INNODB STATUS中的queries inside InnoDB和queries in queue counters两个计数器。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_thread_sleep_delay=#
设定InnoDB线程在加入InnoDB队列以前的睡眠时长,单位是毫秒,默认值为10000。0值表示禁止睡眠而直接加入队列。做用范围为全局级别,可用于选项文件,属动态变量。
 
innodb_use_native_aio={ON|OFF}
设定InnoDB是否使用Linux的异步I/O子系统,所以,其仅应用于Linux系统平台,且MySQL启动后不能更改其值。InnoDB默认会启用此功能,而InnoDB若是由于Linux的异步I/O子系统的问题而没法正常启动,能够在选项文件中将此变量设置为OFF并从新启动之。事实上,就算变量值为ON,若是MySQL服务启动探测到了潜在的问题如联合的临时目录路径、tmpfs文件系统以及Linux内核不支持在tmpfs上使用AIO机制时也会自动关闭此变量。做用范围为全局级别,可用于选项文件,属非动态变量。
 
innodb_use_sys_malloc={ON|OFF}
设定InnoDB使用操做系统的(ON)仍是自有的(OFF)内存分配器。默认值为ON。
 
innodb_version=STRING
InnoDB存储引擎的版本号,只读变量。
 
innodb_write_io_threads={1 .. 64}
设定InnoDB用于完成写操做的I/O线程数量,默认为4个。
 
 
附:InnoDB的数据字典指的是跟踪InnoDB相关的对象如表、索引或表中的字段等的元数据信息,这些元数据存储在InnoDB的系统表空间中(system tablespace)。历史地缘由,它跟.frm文件中的某些数据有重叠的地方。
常见变量说明

若是想查看MySQL相关的某些属性可使用 like ''%属性% ''进行模糊匹配;

mysql> show variables like '%属性名称%';
mysql> show variables like '%data%';
+-------------------------------+------------------------+
| Variable_name                 | Value                  |
+-------------------------------+------------------------+
| character_set_database        | utf8                   |
| collation_database            | utf8_general_ci        |
| datadir                       | /usr/local/mysql/data/ |
| innodb_data_file_path         | ibdata1:12M:autoextend |
| innodb_data_home_dir          |                        |
| innodb_stats_on_metadata      | OFF                    |
| max_length_for_sort_data      | 1024                   |
| metadata_locks_cache_size     | 1024                   |
| metadata_locks_hash_instances | 8                      |
| myisam_data_pointer_size      | 6                      |
| skip_show_database            | OFF                    |
| updatable_views_with_limit    | YES                    |
+-------------------------------+------------------------+
12 rows in set (0.00 sec)
data相关
mysql> show variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | InnoDB |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | InnoDB |
+----------------------------+--------+
3 rows in set (0.00 sec)
数据库引擎相关

 

 

 2.运行状态变量show status

 能够经过show status,查看MySQL的运行状态的相关变量来了解MySQL的相关状态,做为开发人员咱们能够把这些数据分析展现给DBA;

 

 6、MySQL日志

MySQL的日志分为如下几类:

错误日志:记录错误信息(运维关心)

查询日志:记录用户执行的SQL语句

慢查询日志:记录执行速度慢的SQL的

事物日志

二进制日志

中继日志

 

1.查询日志

查询日志是记录用户输入SQL,不只能够记录到文件,还能够输出到表中,知道怎么跑路了吗?小伙?

开启查询日志功能

mysql> set global general_log=on;      #开启查询日志功能
Query OK, 0 rows affected (0.08 sec)

mysql> set global log_output='table'; #设置查询日志输出到表中

只有你开启了查询日志功能并指定了日志的输出MySQL就会把数据输出到表(MySQL库中的general_log表)或配置的log文件中

mysql> select * from general_log;

 

 2.慢查询日志

在你设置一个慢查时长以后,若是SQL从开始<---->结束执行所花费的时间大于该时间,那么慢日志记录该SQL;

这些慢日志对于DBA来讲很是有价值,它们就是基于这些作SQL优化的;

 

查看默认设置的慢日志时间阀值(10秒能够精确到微秒)

mysql> show global variables like '%long%';
+--------------------------------------------------------+-----------+
| Variable_name                                          | Value     |
+--------------------------------------------------------+-----------+
| long_query_time                                        | 10.000000 |
| performance_schema_events_stages_history_long_size     | 10000     |
| performance_schema_events_statements_history_long_size | 10000     |
| performance_schema_events_waits_history_long_size      | 10000     |
+--------------------------------------------------------+-----------+
4 rows in set (0.02 sec)
set global slow_query_log=on; #开启记录慢查询日志功能

 若是设置了log_output =TABLE,MySQL的慢查日志存在mysql库的slow_log表;

mysql> select * from slow_log;

 

 3.事物日志

MySQL的innodb搜素引擎才支持事物,须要注意:全部的事物操做都不会当即同步到数据库执行,而是先记录到事物日志文件;因为事物日志按期向数据库提交;

事物日志须要至少2文件记录提交事物,这两个文件是轮转的,1个写满写另外一个;

mysql> show global variables like '%innodb_log%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 8388608  |  #
| innodb_log_compressed_pages | ON       | 
| innodb_log_file_size        | 50331648 |  #事物日志的大小
| innodb_log_files_in_group   | 2        |  #指定事物日志文件个个数
| innodb_log_group_home_dir   | ./       |  #innodb事物日志所在的目录 
+-----------------------------+----------+
5 rows in set (0.01 sec)

| innodb_flush_log_at_trx_commit #一旦事物提交同步到事物日志,1=每隔1秒钟同步1次,不管是否提交事物;2=只有事物提交才同步

 

4.二进制日志

4.1 什么是二进制日志文件?

记录修改数据或者有可能引发数据修改的SQL语句,因此select语句是不会记录进来的;

 

4.2 什么是主从复制?

那么S数据库不断得读取并执行M数据库产生的二进制个文件,致使S数据库=M数据库,这种技术手段就是主从复制;

 

4.3 MySQL二进制的格式有哪些?

若是 Master执行SQL包含获取当前时间的函数,Save再去经过二进制日志执行中间的时差势必会致使数据库不一致,因此仅记录SQL语句是不能完成主从复制的;还须要记录数据;

 

二进制日志格式有如下3种

SQL语句:statement

行数据:row

 混合:mixed

 

4.4 开启二进制日志

log-bin=mysql-bin               #开启二进制日志
server-id = 1                   #主数据库id为1,不能相同。
replicate_wild_do_table=web.%  #只同步test库下的表
/etc/my.conf
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.07 sec)

 

 4.5 查看当前MySQL的二进制日志

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+

 查看主

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+
1 row in set (0.01 sec)

 

执行flush logs操做会生成一个新的binlog文件

mysql> flush logs;
Query OK, 0 rows affected (0.03 sec)

 

 

查看当前使用的二进制日志

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

 

 

查看二进制日志事件

mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                                                              |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------+
| mysql-bin.000001 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.19-log, Binlog ver: 4                                             |
| mysql-bin.000001 | 120 | Query       |         1 |         241 | create database python default charset=utf8                                       |
| mysql-bin.000001 | 241 | Query       |         1 |         386 | use `python`; create table t5 (id int auto_increment primary key,name varchar(9)) |
| mysql-bin.000001 | 386 | Query       |         1 |         469 | BEGIN                                                                             |
| mysql-bin.000001 | 469 | Query       |         1 |         591 | use `python`; insert into t5(id,name) values(1,"zhanggen")                        |
| mysql-bin.000001 | 591 | Xid         |         1 |         622 | COMMIT /* xid=22 */                                                               |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------+
6 rows in set (0.00 sec)

 

 

 4.6 经过sql_log_bin控制会话级别临时开启关闭记录二进制功能;

在数据库恢复的时候 临时关闭二进制文件记录功能,是为了排除恢复过程当中产生的SQL写入二进制文件;

mysql> set sql_log_bin='OFF';
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%sql_log_bin%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin   | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> set sql_log_bin='on';
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%sql_log_bin%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin   | ON    |
+---------------+-------+
1 row in set (0.00 sec)

 

4.7 mysqlbinlog 

mysqlbinlog 是mysql自带的二进制日志管理工具,利用它的截取功能能够基于彻底备份的数据+二进制日志,作彻底备份时间节点以后任意时间的数据恢复工做了;

 

使用mysqlbinlog 截取 某段时间内(2018-12-01 16:50:00----2018-12-04 16:55:00)产生的二进制日志文件内容;

stdin,stdout,stderr = ssh.exec_command('mysqlbinlog --start-date="2018-12-01 16:50:00" --stop-date="2018-12-04 16:55:00" /usr/local/mysql/data/mysql-bin.00000*')
data=stdout.read().decode('utf-8')
for i in data.split('/n'):
    print(i)

 

使用mysqlbinlog 截取 某个时间节点以前(2018-12-04 16:55:00)产生的二进制日志文件内容;

stdin,stdout,stderr = ssh.exec_command('mysqlbinlog --stop-date="2018-12-04 16:55:00" /usr/local/mysql/data/mysql-bin.00000*')

 

 使用截取的二进制日志文件 数据恢复

[root@localhost zhanggen]# mysql -umartin -p123.com < /tmp/first.sql 
Warning: Using a password on the command line interface can be insecure.

 

 

 

 

 

5.中继日志

主从架构的MySQL, 从MySQL经过远程不断从 主MySQL同步二进制日志 存储在中继日志,从读取中继日志并执行达到主从同步的效果;

(中继日志 = 主服务器上的二进制日志)

 

 

7、MySQL备份

数据库就像企业的心脏,产生数据(血液)输送到各个业务线处理以后回流到心脏,循环往复,所依对它的备份、灾难状况下能够还原相当重要;

磁盘阵列(Redundant Arrays of Independent Drives,RAID)只能在硬件层面保证1块硬盘损坏以后数据不丢失,RAID没法保证用户层面的逻辑操做(本身删个库);

 

1.为何要作数据备份?

灾难恢复:数据丢失的状况下快速恢复数据;(最多见场景)

需求改变:数据回滚到某1时间节点;

测试:能够复制数据还原到测试环境,以便测试;

 

2.备份须要考虑的问题?

可容忍丢失多长时间的数据?

恢复是是否须要暂停业务?

恢复在多长时间内完成?

 

3.备份类型

3.1:根据是否须要数据库离线的标准划分

冷备:MySQL服务库暂停,读写请求均不容许;

温备:MySQL服务在线,备份时仅支持读请求,不支持写请求;

热备:备份同时MySQL服务、读请求、写请求不受影响(MyISAM存储引擎不支持热备,innoDB存储引擎支持)

 

3.2:根据每次备份的数据量 划分

彻底备份(Full Backup):没次备份整个数据量;

 

增量备份(Icreamental Backup):自上1次彻底备份、增长备份以后 增长的数据量;

PS:若是天天都作彻底备份,数据恢复的时候方便,可是备份效率低下,因此增量备份须要依赖彻底备份,是彻底备份的辅助策略;

备份策略:

Sunday彻底备份

+ Monday增量备份 + Tuesday增量备份 +Wednesday增量备份 +Thursday增量备份 +Thursday增量备份 + Thursday增量备份

 

 

恢复策略:

哈哈...若是按以上的备份策略,周六出现紧急情况,须要恢复数据,难度就比较大了,你须要拿着 Last Sunday + Monday+.....Fridy

 

差别备份(Difference Backup):

差别备份就是作1次彻底备份以后,而后天天产出的增量数据 汇聚到同一个地方备份;

差别备份比较容易恢复:由于只有2个数据集;

 

 PS:若是我周1 0点作了1次彻底备份,日后一周时间内天天0点作1次增量备份,那周六晚上18点服务器宕机了(等于周六的增量备份失败了),那我怎么恢复呢?

固然是二进制日志啦!因此你在每次备份以后必定要flush logs;一下产生1个新的二进制日志文件标记一下;

2个增量备份时间节点中间出现了岔子,才能够利用上二进制日志;

 

总结:

到底使用增量备份仍是差别备份根据本身的业务场景,都须要依赖彻底备份,

 其实增量备份 差别备份 只是把增量数据 放在1起存储  仍是不放到一块儿存的不一样;

不管使用增量备份仍是差别备份策略都须要 用得二进制日志;

恢复   =   彻底备份 + 增量1 +增量1 ....  + 二进制日志

 恢复   =  彻底备份     +         差别备份   + 二进制日志

 

3.3:根据备份的数据类型不一样分为

物理备份:备份数据文件

优:

备份恢复都比较简单、快速

劣:

不能作热备

 

逻辑备份:备份表中的数据+代码

优:

恢复简单

备份结果为ASCII文件,可编辑

与存储引擎引擎无关

能够经过网络备份和恢复

 

劣: 

备份和恢复都须要MySQL进程参与,不能暂停MySQL服务

备份结果占据更多磁盘空间

浮动数丢失精度

还原以后索引须要重建

 

4.备份对象

数据:库、表、索引

配置:MySQL配置文件、OS相关的配置文件、主从复制相关的配置

SQL代码:存储过程、函数、触发器...

日志:二进制日志、查询日志、慢查询日志

 

5.备份工具介绍

5.1 mysqldump

MySQLdump是一款 传统、经典的逻辑备份工具,innodb存储引擎支持热备、myisam存储引擎支持温备,备份和恢复较慢;

 

备份整个MySQL服务(全部数据库)

[root@localhost /]# mysqldump -umartin -p123.com --master-data=2 -a --lock-all-tables > /tmp/all_database.sql
ps: -a 参备份因此数据库

 

部分数据库

[root@svnnew ~]# mysqldump -uwebproject -pweb --master-data=2 --databases web mysql --lock-all-tables > /tmp/web_and_mysl.sql
#记录二进制日志位置 #备份的全部数 #施加读锁
ps:--single-transaction 参数能够实现innodb的热备,不须要
--lock-all-tables
[root@localhost /]# less /tmp/mysql.sql 

部分表

表中的某些行

存储过程

存储函数

触发器

自动记录二进制文件以及相应positon

 

-e,  --events:   同时备份事件调度器代码
-r,  --routines: 同时备份存储过程和存储函数
-d,  --no-data: 只备份表结构不备份数据
--opt

 

 

 

 

5.2 mysqldumper

mysqldum的增强版,多线程备份工具; 

 

5.3 select 表备份功能

逻辑备份工具,一般用于备份单表;

select into outfile

select * from cmdb_userinfo where id >7 into outfile '/tmp/lg7_users';    #注意mysql用户一点要对备份的目录有写入权限

load data infile 

mysql> load data infile '/tmp/lg7_users' into table cmdb_userinfo;

 

 

5.4 lvm-snapshot (LVM 快照)

一款接近热备的备份工具,备份时须要施加读锁;

 

5.5 xtrabackup

xtrabackuo是ibbackup的开源版本,物理备份工具,支持innodb热备,对于MyISAM仅支持温备,备份速度快;

 

 

 

 

5.6 mysqlhotcopy

mysql自带 冷备工具

 

 

6.数据备份以后恢复步骤

中止MySQL服务(若是冷备)

记录MySQL服务的配置和文件权限

复制备份文件至数据目录

启动服务

装置逻辑备份

测试数据还原完成

已彻底权限重启MySQL了

 

8、percona-toolkit工具

percona-toolkit工具包同percona-xtrabackup同样都是用Perl写的工具包,percona-toolkit工具包是一组高级的管理mysql的工具包集,本地、远程分析日志;

能够用它采集的数据作MySQL性能分析;

 

1.安装

[root@db ~]# ldconfig -p | grep mysql

那就添加一下:
[root@db ~]# echo '/usr/local/mysql/lib' > /etc/ld.so.conf.d/mysql.conf
[root@db ~]# ldconfig
[root@db ~]# ldconfig -p | grep mysql
出现install_driver(mysql) failed: Attempt to reload DBD/mysql.pm aborted报错

 

2.使用 

分析日志并产生报告

pt-query-digest mysql-bin.00000*

 

分析最近12小时以内的二进制日志 

 

 

 

mysql配置和status进行汇总

pt-mysql-summary  --user=webproject --password='xxxxxx1234'  --port=3306  --host=172.17.10.112

 

 分析参数,并提出建议

pt-variable-advisor --user=webproject --password=xxxxxx1234  172.17.10.112

 

查找和显示指定的Master 有多少个Slave

pt-slave-find --user=webproject --password=xxxxxx1234  --port=3306  --host=172.17.10.112

 

查询重复索引

 pt-duplicate-key-checker  --user=webproject --password='xxxxxx1234'  --port=3306  --host=172.17.10.112

 

性能相关

 

把查询结果输出到数据库

 pt-query-digest --user='martin' --password='123.com' --review  h=127.0.0.1,D=test,t=query_review--create-review-table mysql-bin.00000*

 

 

9、python操做Oracle

import cx_Oracle
orcle_db = cx_Oracle.connect('sys','oracle123','10.102.6.38:1521/historydb',cx_Oracle.SYSDBA)
cursor = orcle_db.cursor()
cursor.execute('select sysdate from dual')
data=cursor.fetchall()
print(data)
cx_Oracle API

虽然Oracle提供了pythonAPI可是,必需要求API的版本和数据库的版本一致。

import paramiko,time
ssh = paramiko.SSHClient()
ssh._policy = paramiko.AutoAddPolicy()
ssh.connect(hostname='10.102.6.38',port=22, username='oracle',password='oracle')
# ssh.connect(hostname='10.102.6.38',port=22, username='root',password='EC_history&LINGzhi')
# ssh.exec_command('source /home/oracle/.bash_profile')
sql="echo 'show parameter;'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus sys/oracle123 as sysdba"
# ssh.exec_command('export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1')

sql1="echo 'select sysdate from dual;'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus scott/tiger@172.16.22.25/pimdb"
#
# ssh.exec_command('export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1')
stdin,stdout,stderr=ssh.exec_command('. ./.bash_profile;%s'%(sql))

data=stdout.read().decode('utf-8').split('\n')[11:-3]
for row in data:
    print(row)
经过paramiko自定义Oracle API
#操做 Oracle、MySQL、Redis的shell和API
class DB_API(object):
    def __init__(self,db_obj):
        self.host = db_obj.db.host
        self.user = db_obj.db_user.username
        self.pwd = db_obj.db_user.password
        self.port = db_obj.db.port
        self.type = db_obj.db.get_database_type_display()
        self.sid=db_obj.db_user.sid

    def call_api(self,sql):
        print('输入%s的sql语句,返回执行结果,redis返回链接对象...'% (self.type))
        self.sql=sql
        db_engin = getattr(self,self.type)
        return db_engin()

    def Redis(self):
        conn_pool = redis.ConnectionPool(host=self.host, port=self.port, db=2, password=self.pwd)
        conn = redis.Redis(connection_pool=conn_pool)
        return conn

    def MySQL(self):
        db = pymysql.connect(self.host, self.user, self.pwd, 'mysql')
        cursor = db.cursor()
        cursor.execute(self.sql)
        data = cursor.fetchall()
        return data

    def Oracle(self):
        import cx_Oracle
        #orcle_db = cx_Oracle.connect('sys','oracle123','10.102.6.38:1521/historydb',cx_Oracle.SYSDBA)
        orcle_db = cx_Oracle.connect(self.user,self.pwd ,self.host+':'+self.port+'/'+self.sid,cx_Oracle.SYSDBA)
        cursor = orcle_db.cursor()
        cursor.execute(self.sql)
        data=cursor.fetchall()
        return data

    def generate_shell_cmd(self,sql):
        shell_cmd_dict = {
            'Redis': "echo '{sql}'| redis-cli -h {host} -p {port} -a {pwd}{user}",
            'MySQL': 'mysql -h{host} -u{user} -p{pwd} -Dmysql -e"{sql}"',
            'Oracle': [
                        ". ./.bash_profile; echo -e 'set pagesize 0\n {sql}'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus -S {user}/{pwd}@{host}/" +self.sid+" as sysdba",
                         ". ./.bash_profile; echo -e 'set pagesize 0\n {sql}'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus -S {user}/{pwd}@{host}/" + self.sid,
                       ]
        }
        if self.type=='Oracle' and self.user=='sys':
            shell_cmd =shell_cmd_dict.get(self.type)[0].format(user=self.user,pwd=self.pwd, sql=sql, host=self.host, port=self.port)
        elif self.type=='Oracle' and self.user!='sys':
            shell_cmd = shell_cmd_dict.get(self.type)[1].format(user=self.user, pwd=self.pwd, sql=sql, host=self.host, port=self.port)
        else:
            shell_cmd = shell_cmd_dict.get(self.type).format(user=self.user,pwd=self.pwd,sql=sql,host=self.host, port=self.port)
        print(shell_cmd)
        return shell_cmd

    def call_shell(self,sql):
        cmd_str = self.generate_shell_cmd(sql)
        if sys.platform == 'linux' and self.type != 'Oracle':
            task_obj = subprocess.Popen(cmd_str, stdout=subprocess.PIPE, shell=True, stderr=subprocess.PIPE)
            ret = task_obj.stdout.read().decode('utf-8') or task_obj.stderr.read().decode('utf-8')
            return ret
        else:
            ssh = paramiko.SSHClient()
            ssh._policy = paramiko.AutoAddPolicy()
            if self.type == 'Oracle':
                ssh.connect(hostname='10.102.6.38', port=22, username='oracle', password='oracle')
            else:
                ssh.connect(hostname='172.17.10.112', port=22, username='root', password='xxxxxx1234')
            stdin, stdout, stderr = ssh.exec_command(cmd_str)
            ret = stdout.read().decode('utf-8') or stderr.read().decode('utf-8')
            return ret

    def get_info(self):
        data = '获取失败!!'
        if self.type == 'Oracle':
            data = self.call_shell('show parameter;')
        elif self.type == 'MySQL':
            data = self.call_shell('show variables;')
        elif self.type== 'Redis':
            data = self.call_shell('info')
        return data
操做 Oracle、MySQL、Redis的shell的统一API

 

我想作  1个 能够统一调用全部DB的API, 之前的思路是 在1台服务器 上经过paramiko 执行 mysql -h、 sqlplus -S、redis-cli -h.....链接客户端链接上DB执行SQL,其实这不是最佳方案,由于SQL执行后 还要对返回结果作数据处理;

from sqlalchemy import create_engine

mysql_con=create_engine('mysql+pymysql://webproject:xxxxxx1234@172.17.10.112:3306/web')
oracle_conn=create_engine('oracle+cx_oracle://scott:tiger@172.16.22.16:1521/ecdb')

for i in mysql_con.execute('show databases'):
    print(i)

for i in oracle_conn.execute('select * from v$version'):
    print(i)
sqlalchemy 版

 

 

 https://www.cnblogs.com/mengfanrong/p/5367748.html

 

 

 

 

 

 

参考博客:http://blog.51cto.com/mageedu/1062628

相关文章
相关标签/搜索