MariaDB or MySQL:

    RDBMS:

        范式:第一范式、第二范式、第三范式;

        表:row, column;

        关系运算:

        选择

        投影

        数据库:表、索引、视图(虚表)、SQL、存储过程、存储函数、触发器、事件调度器;

        DDL:CREATE,ALTER,DROP

        DML:INSERT/UPDATE/DELETE/SELECT

    约束:

        主键约束:惟一、非空;一张表只能有一个;

        惟一键约束:惟一,可以存在多个;

        外键约束:参考性约束;

        检查性约束:check;


    三层模型:

        物理层 --> SA

        逻辑层 --> DBA

        视图层 --> Coder

    实现:

        Oracle, DB2, Sybase, Infomix, SQL Server;

        MySQL, MariaDB, PostgreSQL, SQLite;

        MySQL:

            5.1 --> 5.5 --> 5.6 --> 5.7 --> 8.0

        MariaDB:5.5.x --> 10.x


    特性:

        插件式存储引擎

        单进程多线程


    安装MySQL:

        OS Vendor:rpm 

        MySQL:

            source code:cmake

            binary package:

                        i686, x86_64; 

                        glibc VERSION

            prepackage:rpm, deb

                        os, arch, 


    服务端程序:

            mysqld, mysqld_safe, mysqld_multi

    客户端程序:

            mysql, mysqldump, mysqlbinlog, mysqladmin, ...

    非客户端类管理程序:

            myisamchk, myisampack, ...


        mysqld-5.7

            创建数据目录,属主属组属于运行者用户身份mysql;

            初始化:

                mysqld  --initilize-insecure --basedir=/usr/local/mysql --datadir=/data/mysql --user=mysql

            查看配置文件路径,修改配置文件:/usr/local/mysql/etc/my.cnf

                datadir

                socket

                includedir

                pid

            准备错误日志文件:

            复制启动脚本:/usr/local/mysql/support-files/mysql.server --> /etc/init.d/mysqld


        配置文件:

                读取多处的多个配置文件,而且会以指定的次序的进行; 

            # my_print_defaults

                    Default options are read from the following files in the given order:

                    /etc/mysql/my.cnf  /etc/my.cnf ~/.my.cnf 

                    不同的配置文件中出现同一参数且拥有不同值时,后读取将为最终生效值; 


            修改默认读取的配置文件(mysqld_safe命令):

                    --defaults-file=file_name

            于读取的默认配置文件之外再加载一个文件:

                    --defaults-extra-file=path


        程序文件:

                服务端程序:mysqld_safe, mysqld_multi

                客户端程序:mysql, mysqldump, mysqladmin

                工具程序:myisampack, ...


        mysql --> mysql protocol --> mysqld 

                mysql:交互式CLI工具;

                mysql [options] db_name

                    常用选项:

                        --host=host_name, -h host_name:服务端地址;

                        --user=user_name, -u user_name:用户名;

                        --password[=password], -p[password]:用户密码; 

                        --port=port_num, -P port_num:服务端端口; 

                        --protocol={TCP|SOCKET|PIPE|MEMORY}:

                            本地通信:基于本地回环地址进行请求,将基于本地通信协议;

                                    Linux:SOCKET

                                    Windows:PIPE,MEMORY

                            非本地通信:使用非本地回环地址进行的请求; TCP协议;

                                    --socket=path, -S path

                                    --database=db_name, -D db_name:

                                    --compress, -C:数据压缩传输

                                    --execute=statement, -e statement:非交互模式执行SQL语句;

                                    --vertical, -E:查询结果纵向显示;


            命令:

                    客户端命令:于客户端执行;

                    服务端命令:SQL语句,需要一次性完整地发往服务端;语句必须有结束符;


                        ?         (\?) Synonym for `help'.

                        clear     (\c) Clear the current input statement.

                        connect   (\r) Reconnect to the server. Optional arguments are db and host.

                        delimiter (\d) Set statement delimiter.

                        edit      (\e) Edit command with $EDITOR.

                        ego       (\G) Send command to mysql server, display result vertically.

                        exit      (\q) Exit mysql. Same as quit.

                        go        (\g) Send command to mysql server.

                        help      (\h) Display this help.

                        nopager   (\n) Disable pager, print to stdout.

                        notee     (\t) Don't write into outfile.

                        pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.

                        print     (\p) Print current command.

                        prompt    (\R) Change your mysql prompt.

                        quit      (\q) Quit mysql.

                        rehash    (\#) Rebuild completion hash.

                        source    (\.) Execute an SQL script file. Takes a file name as an argument.

                        status    (\s) Get status information from the server.

                        system    (\!) Execute a system shell command.

                        tee       (\T) Set outfile [to_outfile]. Append everything into given outfile.

                        use       (\u) Use another database. Takes database name as argument.

                        charset   (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.

                        warnings  (\W) Show warnings after every statement.

                        nowarning (\w) Don't show warnings after every statement.

                    

            mysql命令的使用帮助:

                    # man mysql

                    # mysql  --help  --verbose


            sql脚本运行:

                    mysql [options] [DATABASE] < /PATH/FROM/SOME_SQL_SCRIPT


        mysqld服务器程序:工作特性的定义方式

                    命令行选项

                    配置文件参数


                        SHOW [GLOBAL | SESSION] VARIABLES [like_or_where]


                    服务器参数/变量:设定MySQL的运行特性;

                        mysql> SHOW GLOBAL|[SESSION] VARIABLES [LIKE clause];

                    状态(统计)参数/变量:保存MySQL运行中的统计数据或状态数据;

                        mysql> SHOW GLOBA|[SESSION] STATUS [LIKE clause];

                    显示单个变量设定值的方法:

                        mysql> SELECT @@[global.|session.]system_var_name


                            %:匹配任意长度的任意字符;

                            _:匹配任意单个字符;


        变量/参数级别:

                全局:为所有会话设定默认; 

                会话:跟单个会话相关;会话建立会从全局继承;

            服务器变量的调整方式:

                运行时修改:

                    global:仅对修改后新建立的会话有效;

                    session:仅对当前会话有效,且立即生效;

                启动前通过配置文件修改:

                    重启后生效;

                运行时修改变量值操作方法:

                    mysql> HELP SET

                    SET [GLOBAL | SESSION] system_var_name = expr

                    SET [@@global. | @@session. | @@]system_var_name = expr

                    注:GLOBAL值的修改要求用户拥有管理权限;


            安装完成后的安全初始化:

                    mysql_secure_installation


            运行前常修改的参数:

                    innodb_file_per_table=ON

                    skip_name_resolve=ON

                    ...



        MySQL的数据类型:

                字符型

                数值型

                日期时间型

                内建类型

                字符型:

                        CHAR(#), BINARY(#):定长型;CHAR不区分字符大小写,而BINARY区分;

                        VARCHAR(#), VARBINARY(#):变长型

                        TEXT:TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT

                        BLOB:TINYBLOB,BLOB,MEDIUMBLOB, LONGBLOB

               数值型:

                    浮点型:近似

                        FLOAT

                        DOUBLE

                        REAL

                        BIT

                   整型:精确

                        INTEGER:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT

                        DECIMAL

                   日期时间型:

                        日期:DATE

                        时间:TIME

                        日期j时间:DATETIME

                        时间戳:TIMESTAMP

                        年份:YEAR(2), YEAR(4)

                   内建:

                        ENUM:枚举

                        ENUM('Sun','Mon','Tue','Wed')

                    SET:集合


            类型修饰符:

                        字符型:NOT NULL,NULL,DEFALUT ‘STRING’,CHARACET SET ‘CHARSET’,COLLATION ‘collocation'

                        整型:NOT NULL, NULL, DEFALUT value, AUTO_INCREMENT, UNSIGNED

                        日期时间型:NOT NULL, NULL, DEFAULT 


            SQL MODE:定义mysqld对约束等违反时的响应行为等设定;

                    常用的MODE:

                            TRADITIONAL

                            STRICT_TRANS_TABLES

                            STRICT_ALL_TABLES              

                    修改方式:

                            mysql> SET GLOBAL sql_mode='MODE';

                            mysql> SET @@global.sql_mode='MODE';



            SQL:DDL,DML

                      DDL:

                               mysql> HELP Data Definition

                                

                               CREATE, ALTER, DROP

                                            DATABASE, TABLE

                                            INDEX, VIEW, USER

                                            FUNCTION, FUNCTION UDF, PROCEDURE, TABLESPACE, TRIGGER, SERVER 

                                

                     DML:

                                mysql> HELP Data Manipulation

                                

                                INSERT/REPLACE, DELETE, SELECT, UPDATE

                                

                     数据库:

                                CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name CHARACTER SET [=] charset_name  COLLATE [=] collation_name

                                

                                ALTER {DATABASE | SCHEMA} [db_name] CHARACTER SET [=] charset_name  COLLATE [=] collation_name

                                

                                DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

                                

                       表:

                           CREATE 

                                (1) CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name

                                        (create_definition,...)

                                        [table_options]

                                        [partition_options]

                                

                                        CREATE TABLE [IF NOT EXISTS] tble_name (col_name  data_typ|INDEX|CONSTRAINT);

                                

                                table_options:

                                        ENGINE [=] engine_name

                                

                                查看支持的所有存储引擎:

                                        mysql> SHOW ENGINES;

                                

                                查看指定表的存储引擎:

                                        mysql> SHOW TABLE STATUS LIKE clause;

                                

                                        ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

                                

                                (2) CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name

                                        [(create_definition,...)]

                                        [table_options]

                                        [partition_options]

                                        select_statement

                                            直接创建表,并将查询语句的结果插入到新创建的表中;

                                

                                (3) CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name

                                { LIKE old_tbl_name | (LIKE old_tbl_name) }

                                           复制某存在的表的结构来创建新的空表;

                                

                          DROP:

                                DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name]; 

                                

                          ALTER:

                                ALTER  TABLE tbl_name

                                [alter_specification [, alter_specification] ...]

                                

                                可修改内容:

                                        (1) table_options

                                        (2) 添加定义:ADD

                                                字段、字段集合、索引、约束

                                        (3) 修改字段:

                                                CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name]

                                                MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]

                                        (4) 删除操作:DROP

                                                字段、索引、约束

                                

                                    表重命名:

                                        RENAME [TO|AS] new_tbl_name

                                

                                查看表结构定义:

                                        DESC tbl_name;

                                

                                查看表定义:

                                        SHOW CREATE TABLE tbl_name

                                

                                查看表属性信息:

                                            SHOW TABLE STATUS [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]


                       

                   索引类型:

                            聚集索引、非聚集索引:索引是否与数据存在一起;

                            主键索引、辅助索引

                            稠密索引、稀疏索引:是否索引了每一个数据项;

                            BTREE(B+)、HASH、R Tree、FULLTEXT

                            BTREE:左前缀;

                            

                            EXPLAIN:分析查询语句的执行路径;

                    索引:

                            创建:

                            CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...)

                            

                            查看:

                            SHOW {INDEX | INDEXES | KEYS} {FROM | IN} tbl_name [{FROM | IN} db_name] [WHERE expr]

                            

                            删除:

                            DROP  INDEX index_name ON tbl_name

                            

                            

                    视图:VIEW

                            虚表:存储下来的SELECT语句;

                            

                            创建:

                            CREATE  VIEW view_name [(column_list)] AS select_statement

                            

                            修改:

                            ALTER  VIEW view_name [(column_list)] AS select_statement

                            

                            删除:

                            DROP VIEW [IF EXISTS] view_name [, view_name] ...



DML:

                INSERT/REPLACE,DELETE,UPDATE,SELECT

                

                INSERT:

                单行插入

                批量插入

                

                INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]

                [INTO] tbl_name [(col_name,...)]

                {VALUES | VALUE} ({expr | DEFAULT},...),(...),...

                [ ON DUPLICATE KEY UPDATE

                col_name=expr

                [, col_name=expr] ... ]

                

                Or:

                

                INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]

                [INTO] tbl_name

                SET col_name={expr | DEFAULT}, ...

                [ ON DUPLICATE KEY UPDATE

                col_name=expr

                [, col_name=expr] ... ]

                

                Or:

                

                INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]

                [INTO] tbl_name [(col_name,...)]

                SELECT ...

                [ ON DUPLICATE KEY UPDATE

                col_name=expr

                [, col_name=expr] ... ]

                

                DELETE:

                

                DELETE  FROM tbl_name [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]

                

                注意:一定要有限制条件,否则将清空整个表;

                限制条件:

                [WHERE where_condition]

                 [ORDER BY ...] [LIMIT row_count]

                 

                UPDATE:

                

                UPDATE table_reference SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...

                [WHERE where_condition]

                [ORDER BY ...]

                [LIMIT row_count]

                

                注意:一定要有限制条件,否则将修改整个表中指定字段的数据;

                限制条件:

                [WHERE where_condition]

                 [ORDER BY ...] [LIMIT row_count]

                 

                

                注意:sql_safe_updates变量可阻止不带条件更新操作;

                

                SELECT:

                

                Query Cache:缓存查询的执行结果;

                key:查询语句的hash值; 

                value:查询语句的执行结果;

                

                SQL语句的编写方式:

                SELECT name FROM tbl2;

                select name from tbl2;

                

                查询执行路径:

                请求-->查询缓存

                请求-->查询缓存-->解析器-->预处理器-->优化器-->查询执行引擎-->存储引擎-->缓存-->响应

                

                

                SELECT语句的执行流程:

                FROM  --> WHERE --> Group By --> Having --> Order BY --> SELECT --> Limit 

                

                单表查询:

                        SELECT

                        [ALL | DISTINCT | DISTINCTROW ]

                        [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]

                        select_expr [, select_expr ...]

                        [FROM table_references

                        [WHERE where_condition]

                        [GROUP BY {col_name | expr | position}

                        [ASC | DESC], ... [WITH ROLLUP]]

                        [HAVING where_condition]

                        [ORDER BY {col_name | expr | position}

                        [ASC | DESC], ...]

                        [LIMIT {[offset,] row_count | row_count OFFSET offset}]

                                    用法:

                                    SELECT col1, col2, ... FROM tble_name;   极其危险,慎用;

                                    SELECT col1, col2, ... FROM tble_name WHERE clause;

                                    SELECT col1, col2, ... FROM tble_name  [WHERE clause] GROUP BY col_name [HAVING clause]; 

                                    

                                    DISTINCT:数据去重;

                                    SQL_CACHE:显式指定缓存查询语句的结果;

                                    SQL_NO_CACHE:显式指定不缓存查询语句的结果;

                                    

                                    query_cache_type服务器变量有三个值:

                                    ON:启用; 

                                    SQL_NO_CACHE:不缓存;默认符合缓存条件都缓存;

                                    OFF:关闭;

                                    DEMAND:按需缓存;

                                    SQL_CACHE:缓存;默认不缓存;

                                    

                                    字段可以使用别名 :

                                    col1 AS alias1, col2 AS alias2, ...

                                    

                                    WHERE子句:指明过滤条件以实现“选择”功能;

                                    过滤条件:布尔型表达式;

                                    

                                    [WHERE where_condition]

                                    算术操作符:+, -, *, /, %

                                    比较操作符:=, <>, !=, <=>, >, >=, <, <=

                                    

                                    IS NULL, IS NOT NULL

                                    区间:BETWEEN min AND max 

                                    IN:列表;

                                    LIKE:模糊比较,%和_;

                                    RLIKE或REGEXP

                                    

                                    逻辑操作符:

                                    AND, OR, NOT

                                    

                                    GROUP BY:根据指定的字段把查询的结果进行“分组”以用于“聚合”运算;

                                    avg(), max(), min(), sum(), count()

                                    

                                    HAVING:对分组聚合后的结果进行条件过滤;

                                    

                                    ORDER BY:根据指定的字段把查询的结果进行排序;

                                    升序:ASC

                                    降序:DESC 

                                    

                                    LIMIT:对输出结果进行数量限制

                                    [LIMIT {[offset,] row_count | row_count OFFSET offset}]



            多表查询:

            连接操作:

                        交叉连接(cross join):笛卡尔乘积;没有任何条件限制的连接方式

                                示例:select * from tb1,tb2;

                                          select * from tb1 cross join tb2;

                        内连接(inner join):多张表中同时符合某种条件的数据记录的组合;官方建议标准写法:select * from tb1 inner join tb2 on tb1.tid=tb2.bid;

                                等值连接:使用“=”作为连接条件连接两张表;

                                    示例:select * from tb1,tb2 where tb1.tid=tb2.bid;

                                不等值连接:没有使用“=”作为连接条件连接两张表;

                                    示例:select * from tb1,tb2 where tb1.tid>tb2.bid;

                                    示例:select * from tb1,tb2 where tb1.tid

                                自连接:连接的表为一张表,即自己连接自己;

                                    示例:select * from tb1,tb1 where tb1.tid=tb1.id;

                                自然连接(natural join):通过MySql自己的判断完成连接过程,不需要指定连接条件。MySql会使用表内的,相同的字段,作为连接条件

                                    示例:select * from tb1 natural join tb2;   


                      外连接:

                                左外连接:以左表为基准连接两表,即左表的所有数据都展示出来,符合条件的相互连接,不符合条件记录跟右侧的“空记录”连接

                                FROM tb1 LEFT JOIN tb2 ON tb1.col = tb2.col 

                                右外连接:以右表为基准连接两表,即右表的所有数据都展示出来,符合条件的相互连接,不符合条件记录跟左侧的“空记录”连接

                                FROM tb1 RIGHT JOIN tb2 ON tb1.col = tb2.col 


                        全连接(full join):会把两个表所有的行都显示在结果表中mariadb不能直接使用full join实现全连接;变相实现方式为left join、union、right join组合来实现;

                                示例:select * from tb1 left join tb2 on tb1.tid=tb2.id union select * from tb1 right join tb2 on tb1.tid=tb2.id;

            

            子查询:在查询中嵌套查询;

                    用于WHERE子句中的子查询;

                    (1) 用于比较表达式中的子查询:子查询仅能返回单个值; 

                    (2) 用于IN中的子查询:子查询可以返回一个列表值; 

                    (3) 用于EXISTS中的子查询:

                    用于FROM子句中的子查询;

                    SELECT tb_alias.col1, ... FROM (SELECT clause) AS tb_alias WHERE clause; 

            

            联合查询:将多个查询语句的执行结果相合并;

                        UNION:重复的数据会被合并为一条;

                                    SELECT clause UNION SELECT cluase;                       

                        UNION ALL:不合并重复的数据;

                                    SELECT clause UNION ALL SELECT cluase;



      MySQL用户和权限管理 

                用户账号:user@host

                user:账户名称;

                host:此账户可通过哪些客户端主机请求创建连接线程; 

                %:任意长度牟任意字符;

                _:任意单个字符;

                

                skip_name_resolve=ON

        MySQL权限类别:

        库级别:

        表级别:

        字段级别:

        管理类:

        程序类:

                        管理类:

                        CREATE USER

                        RELOAD

                        LOCK TABLES

                        REPLICATION CLIENT, REPLICATION SLAVE

                        SHUTDOWN

                        FILE

                        SHOW DATABASES

                        PROCESS 

                        SUPER

                        

                        程序类:

                        FUNCTION,PROCEDURE,TRIGGER

                        

                        操作:CREATE,ALTER,DROP,EXECUTE

                        

                        库和表级别:

                        CREATE,ALTER,DROP

                        INDEX

                        CREATE VIEW

                        SHOW VIEW

                        GRANT:能够把自己获得的权限生成一个副本转赠给其它用户;

                        OPTION

            数据操作:

            表:

            INSERT/DELETE/UPDATE/SELECT 

            

            字段:

            SELECT(col1,col2,...)

            UPDATE(col1,col2,...)

            INSERT(col1,col2,...)

            

            所有权限:ALL, ALL PRIVILEGES

            

            元数据数据库(数据字典):mysql

            授权:

            db, host, user

            tables_priv, column_priv, procs_priv, proxies_priv

            

            

            MySQL用户管理:

            'user'@'host';

            host:

            IP

            主机名

            NETWORK

            %, _

            

            skip_name_resolve={ON|OFF}


        创建用户:

        CREATE USER  'user'@'host' [IDENTIFIED BY [PASSWORD] 'password'] [,'user'@'host' [IDENTIFIED BY [PASSWORD] 'password']...]

        

        重命名:RENAME USER

        RENAME USER old_user TO new_user[, old_user TO new_user] ...

        

        删除用户:

        DROP USER 'user'@'host' [, 'user'@'host'] ...

        

        让MySQL重新加载授权表:

        FLUSH PRIVILEGES

        

        修改用户密码:

        (1) SET PASSWORD [FOR 'user'@'host'] = PASSWORD('cleartext password');

        (2) UPDATE mysql.user SET Password=PASSWORD('cleartext password')  WHERE User='USERNAME' AND Host='HOST';

        (3) mysqladmin -uUSERNAME -hHOST -p  password 'NEW_PASS'

        

        生效:FLUSH PRIVILEGES

        

        忘记管理员密码的解决办法:

        (1) 启动mysqld进程时,使用--skip-grant-tables和--skip-networking选项;

        CentOS 7:mariadb.service

        CentOS 6:/etc/init.d/mysqld

        (2) 通过UPDATE命令修改管理员密码; 

        (3) 以正常 方式启动mysqld进程;

        

        授权:GRANT

        GRANT  priv_type [(column_list)] [, priv_type [(column_list)]] ...

        ON [object_type] priv_level

        TO user_specification [, user_specification] ...

        [REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]

        [WITH with_option ...]

        

        object_type:

                TABLE

                | FUNCTION

                | PROCEDURE

        

        priv_level:

                *

                | *.*

                | db_name.*

                | db_name.tbl_name

                | tbl_name

                | db_name.routine_name

        

        

        ssl_option:

                SSL

                | X509

                | CIPHER 'cipher'

                | ISSUER 'issuer'

                | SUBJECT 'subject'

        

        with_option:

                GRANT OPTION

                | MAX_QUERIES_PER_HOUR count

                | MAX_UPDATES_PER_HOUR count

                | MAX_CONNECTIONS_PER_HOUR count

                | MAX_USER_CONNECTIONS count

        

        查看授权:SHOW GRANTS

                SHOW GRANTS [FOR 'user'@'host']

        

        取消授权:REVOKE

                REVOKE  priv_type [(column_list)][, priv_type [(column_list)]] ...

                ON [object_type] priv_level

                FROM  'user'@'host' [,  'user'@'host'] ...

                

                REVOKE ALL PRIVILEGES, GRANT OPTION

                FROM user [, user] ...

        


        查询缓存:完全存储于内存中;

                缓存:k/v 

                key:查询语句的hash值

                value:查询语句的执行结果

        

        

        如何判断缓存是否命中:

                通过查询语句的哈希值判断:哈希值考虑的因素包括

                        查询本身、要查询数据库、客户端使用的协议版本、...

                        查询语句在任何字符上的不同,都会导致缓存不命中;

                

        哪些查询可能不会被缓存?

                查询语句中包含UDF

                存储函数

                用户自定义变量

                临时表

                mysql系统表或者是包含列级别权限的查询

                有着不确定结果值的函数(now());

        

        查询缓存相关的服务器变量:

                query_cache_limit:能够缓存的最大查询结果;(单语句结果集大小上限)

                        有着较大结果集的语句,建议在SELECT中显式使用SQL_NO_CACHE,以避免先缓存再移出; 

                query_cache_min_res_unit:内存块的最小分配单位;缓存过小的查询结果集会浪费内存空间;

                        较小的值会减少空间浪费,但会导致更频繁地内存分配及回收操作; 

                        较大值的会带来空间浪费,导致碎片过多;

                query_cache_size:查询缓存空间的总共可用的大小;单位是字节,必须是1024的整数倍;

                query_cache_strip_comments

                query_cache_type:缓存功能启用与否;

                        ON:启用;

                        OFF:禁用;

                        DEMAND:按需缓存,仅缓存SELECT语句中带SQL_CACHE的查询结果;

                query_cache_wlock_invalidate:如果某表被其它连接锁定,是否仍然可以从查询缓存中返回查询结果;默认为OFF,表示可以;ON则表示不可以;

        

        状态变量:

                mysql> SHOW GLOBAL STATUS LIKE 'Qcache%';

                +-------------------------+----------+

                | Variable_name           | Value    |

                +-------------------------+----------+

                | Qcache_free_blocks      | 1        |

                | Qcache_free_memory      | 16759688 |

                | Qcache_hits             | 0        |

                | Qcache_inserts          | 0        |

                | Qcache_lowmem_prunes    | 0        |

                | Qcache_not_cached       | 0        |

                | Qcache_queries_in_cache | 0        |

                | Qcache_total_blocks     | 1        |

                +-------------------------+----------+

        

                命中率:

                        Qcache_hits/(Qcache_hits+Com_select) 



        MySQL中的索引:

                基本法则:索引应该构建在被用作查询条件的字段上;

                

                索引类型:B+ TREE,HASH

                        B+ TREE:顺序存储,每一个叶子结点到根结点的距离相同;左前缀索引,适合于范围类型的数据查询;


                        适用于B+ TREE索引的查询类型:全键值、键值范围或键前缀;

                                全值匹配:精确匹配某个值;

                                        WHERE COLUMN = 'value';

                                匹配最左前缀:只精确起头的部分;

                                        WEHRE COLUMN LIKE 'PREFIX%';

                                匹配范围值:

                                精确匹配某一列,范围匹配另一列;

                                只用访问索引的查询:覆盖索引;

                                            index(Name)

                                            SELECT Name FROM students WHERE Name LIKE 'L%';


                    不适用B+ TREE索引:

                            如果查条件不是从最左侧列开始,索引无效;

                                    index(age,Fname), WHERE Fname='Jerry';    , WHERE age>30 AND Fname='Smith';

                            不能跳过索引中的某列;

                                    index(name,age,gender)

                                    WHERE name='black' and age > 30;

                                    WHERE name='black' AND gender='F';

                            如果查询中的某个列是为范围查询,那么其右侧的列都无法再使用索引优化查询;

                                    WHERE age>30 AND Fname='Smith';


            Hash索引:基于哈希表实现,特别适用于值的精确匹配查询;

            

            适用场景:

            只支持等值比较查询,例如=, IN(), <=>

            

            不用场景:

            所有非精确值查询;MySQL仅对memory存储引擎支持显式的hash索引;

            

            索引优点:

            降低需要扫描的数据量,减少IO次数;

            可以帮助避免排序操作,避免使用临时表; 

            帮助将随机IO转为顺序IO;

            

            高性能索引策略:

            (1) 在WHERE中独立使用列,尽量避免其参与运算;

            WHERE age+2 > 32 ; 

            (2) 左前缀索引:索引构建于字段的最左侧的多少个字符,要通过索引选择性来评估

            索引选择性:不重复的索引值和数据表的记录总数的比值;

            (3) 多列索引:

            AND连接的多个查询条件更适合使用多列索引,而非多个单键索引;

            (4) 选择合适的索引列次序:选择性最高的放左侧;

            

            EXPLAIN来分析索引有效性:

            

            EXPLAIN [explain_type] SELECT select_options

            

            explain_type:

            EXTENDED

            | PARTITIONS

            

            输出结果:

            id: 1

            select_type: SIMPLE

            table: students

            type: const

            possible_keys: PRIMARY

            key: PRIMARY

            key_len: 4

            ref: const

            rows: 1

            Extra: 

            

            id:当前查询语句中,第个SELECT语句的编号;

            

            复杂的查询的类型主要三种:

            简单子查询

            用于FROM中的子查询

            联合查询

            

            注意:联合查询的分析结果会出现一个额外的匿名临时表;

            

            select_type:查询类型:

            简单查询:SIMPLE

            复杂查询:

            简单子查询:SUBQUERY

            用于FROM中的子查询:DERIVED

            联合查询中的第一个查询:PRIMARY

            联合查询中的第一个查询之后的其它查询:UNION

            联合查询生成的临时表:UNION RESULT

            

            table:查询针对的表;

            

            type:关联类型,或称为访问类型,即MySQL如何去查询表中的行

            ALL:全表扫描;

            index:根据索引的顺序进行的全表扫描;但同时如果Extra列出现了"Using index”表示使用了覆盖索引;

            range:有范围限制地根据索引实现范围扫描;扫描位置始于索引中的某一项,结束于另一项;

            ref:根据索引返回的表中匹配到某单个值的所有行(匹配给定值的行不止一个);

            eq_ref:根据索引返回的表中匹配到某单个值的单一行,仅返回一个行,但需要与某个额外的参考值比较,而不是常数;

            const,system:与某个常数比较,且只返回一行;

            

            possiable_keys:查询中可能会用到的索引;

            

            key:查询中使用的索引;

            

            key_len:查询中用到的索引长度;

            

            ref:在利用key字段所显示的索引完成查询操作时所引用的列或常量值; 

            

            rows:MySQL估计出的为找到所有的目标项而需要读取的行数;

            

            Extra:额外信息

            Using index:使用了覆盖索引进行的查询;

            Using where:拿到数据后还要再次进行过滤; 

            Using temporary:使用了临时表以完成查询;

            Using filesort:对结果使用了一个外部索引排序;



存储引擎:

表类型:也称为“表类型”,表级别概念,不建议在同一个库中的表上使用不同的ENGINE;

CREATE TABLE ... ENGINE[=]STORAGE_ENGINE_NAME ...

SHOW TABLE STATUS 

常见的存储引擎:

MyISAM, Aria, InnoDB, MRG_MYISAM, CSV, BLACKHOLE, MEMORY, PERFORMANCE_SCHEMA, ARCHIVE, FEDERATED

InnoDB:InnoBase

Percona-XtraDB, Supports transactions, row-level locking, and foreign keys

数据存储于“表空间(table space)"中:

(1) 所有数据库中的所有类型为InnoDB的表的数据和索引存储于同一个表空间中;

表空间文件:datadir定义的目录中

文件:ibdata1, ibdata2, ...

(2) innodb_file_per_table=ON,意味着每表使用单独的表空间文件;

每表的数据文件(数据和索引,存储于数据库目录)存储于自己专用的表空间文件中,并存储于数据库目录下: tbl_name.ibd 

表结构的定义:在数据库目录,tbl_name.frm 

事务型存储引擎,适合对事务要求较高的场景中;但较适用于处理大量短期事务;

基于MVCC(Mutli Version Concurrency Control)支持高并发;支持四个隔离级别,默认级别为REPEATABLE-READ;间隙锁以防止幻读;

使用聚集索引(主键索引);

支持”自适应Hash索引“;

锁粒度:行级锁;间隙锁;

总结:

数据存储:表空间;

并发:MVCC,间隙锁,行级锁;

索引:聚集索引、辅助索引;

性能:预读操作、内存数据缓冲、内存索引缓存、自适应Hash索引、插入操作缓存区;

备份:支持热备;

SHOW ENGINE INNODB STATUS;

MyISAM:

支持全文索引(FULLTEXT index)、压缩、空间函数(GIS);

不支持事务


锁力度:表级锁

崩溃无法保证表安全恢复

适用场景:只读或读多写少的场景、较小的表(以保证崩溃后恢复的时间较短);

文件:每个表有三个文件,存储于数据库目录中

tbl_name.frm:表格式定义;

tbl_name.MYD:数据文件; 

tbl_name.MYI:索引文件;

特性:

加锁和并发:表级锁;

修复:手动或自动修复、但可能会丢失数据;

索引:非聚集索引;

延迟索引更新;

表压缩;

行格式:

{DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

 

其它的存储引擎:

CSV:将CSV文件(以逗号分隔字段的文本文件)作为MySQL表文件; 

MRG_MYISAM:将多个MyISAM表合并成的虚拟表;

BLACKHOLE:类似于/dev/null,不真正存储数据;

MEMORY:内存存储引擎,支持hash索引,表级锁,常用于临时表;

FEDERATED: 用于访问其它远程MySQL服务器上表的存储引擎接口;

MariaDB额外支持很多种存储引擎:

OQGraph、SphinxSE、TokuDB、Cassandra、CONNECT、SQUENCE、...

搜索引擎:

lucene, sphinx 

lucene:Solr, ElasticSearch 

        

 


        并发控制:

锁:Lock 

锁类型 :

读锁:共享锁,可被多个读操作共享;

写锁:排它锁,独占锁;

锁粒度:

表锁:在表级别施加锁,并发性较低;

行锁:在行级别施加锁,并发性较高;维持锁状态的成本较大;

锁策略:在锁粒度及数据安全性之间寻求一种平衡机制;

存储引擎:级别以及何时施加或释放锁由存储引擎自行决定;

MySQL Server:表级别,可自行决定,也允许显式请求; 

锁类别:

显式锁:用户手动请求的锁;

隐式锁:存储引擎自行根据需要施加的锁;

显式锁的使用:

(1) LOCK TABLES 

LOCK TABLES  tbl_name  read|write, tbl_name read|write, ...

UNLOCK TABLES

(2) FLUSH TABLES

FLUSH TABLES tbl_name,... [WITH READ LOCK];

UNLOCK TABLES;

(3) SELECT cluase

[FOR UPDATE | LOCK IN SHARE MODE]


事务:

事务:一组原子性的SQL查询、或者是一个或多个SQL语句组成的独立工作单元;

事务日志:

innodb_log_files_in_group

innodb_log_group_home_dir

innodb_log_file_size

innodb_mirrored_log_groups

ACID测试:

A:AUTOMICITY,原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚;

C:CONSISTENCY,一致性;数据库总是应该从一个一致性状态转为另一个一致性状态; 

I:ISOLATION,隔离性;一个事务所做出的操作在提交之前,是否能为其它事务可见;出于保证并发操作之目的,隔离有多种级别; 

D:DURABILITY,持久性;事务一旦提交,其所做出的修改会永久保存;


自动提交:单语句事务   autocommit={0|1};


mysql> SELECT @@autocommit;

+------------------------+

| @@autocommit |

+------------------------+

|            1               |

+------------------------+

mysql> SET @@session.autocommit=0;


手动控制事务:

启动:START TRANSACTION 

提交:COMMIT

回滚:ROLLBACK


事务支持savepoints:

SAVEPOINT identifier               设置一个保存点

ROLLBACK [WORK] TO [SAVEPOINT] identifier         回滚到特定保存点

RELEASE SAVEPOINT identifier                                删除特定保存点     


事务隔离级别:

READ-UNCOMMITTED:读未提交 --> 脏读;

READ-COMMITTED:读提交--> 不可重复读;

REPEATABLE-READ:可重复读 --> 幻读;     mysql默认事务隔离级别;

SERIALIZABLE:串行化;


mysql> SELECT @@session.tx_isolation;

+----------------------------------+

| @@session.tx_isolation |

+----------------------------------+

| REPEATABLE-READ         |

+----------------------------------+

查看InnoDB存储引擎的状态信息:

SHOW ENGINE innodb STATUS; 





centos 7:手动编译安装mariadb

            开发环境:

                # yum groupinstall "development tools" -y 

            一、安装其他所需;

                # yum install ncurses-devel openssl-devel libevent-devel jemalloc-devel cmake

            二、下载mariadb源码包,编译安装      

                # groupadd -r mysql

                # useradd -g mysql -r -d /mydata/data mysql

                # tar xf mysql-5.5.33.tar.gz 

                # cd mysql-5.5.33

                # cmake   .  -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \

                                  -DMYSQL_DATADIR=/mydata/data \

                                  -DSYSCONFDIR=/etc \

                  -DWITH_INNOBASE_STORAGE_ENGINE=1 \

                                  -DWITH_ARCHIVE_STORAGE_ENGINE=1 \

                                  -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

                  -DWITH_READLINE=1 \

                  -DWITH_SSL=system \

                  -DWITH_ZLIB=system \

                  -DWITH_LIBWRAP=0 \

                  -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \

                  -DDEFAULT_CHARSET=utf8 \

                                  -DDEFAULT_COLLATION=utf8_general_ci

                # make 

                # make install

            三、手动创建systemv文件,样例如下:/usr/lib/systemd/system/mariadb.service

                            [Unit]

                            Description=MariaDB database server

                            After=syslog.target

                            After=network.target

                            

                            [Service]

                            Type=simple

                            User=mysql

                            Group=mysql

                            

                            ExecStartPre=/usr/libexec/mariadb-prepare-db-dir %n

                            # Note: we set --basedir to prevent probes that might trigger SELinux alarms,

                            # per bug #547485

                            ExecStart=/usr/bin/mysqld_safe --basedir=/usr

                            ExecStartPost=/usr/libexec/mariadb-wait-ready $MAINPID

                            

                            # Give a reasonable amount of time for the server to start up/shut down

                            TimeoutSec=300

                            

                            # Place temp files in a secure directory, not /tmp

                            PrivateTmp=true

                            

                            [Install]

                            WantedBy=multi-user.target


                        四、手动执行# systemctl daemon-reload加载;

                            

                

        指定安装文件的安装路径时常用的选项:

        -DCMAKE_INSTALL_PREFIX=/usr/local/mysql

        -DMYSQL_DATADIR=/data/mysql

        -DSYSCONFDIR=/etc


        默认编译的存储引擎包括:csv、myisam、myisammrg和heap。若要安装其它存储引擎,可以使用类似如下编译选项:

        -DWITH_INNOBASE_STORAGE_ENGINE=1

        -DWITH_ARCHIVE_STORAGE_ENGINE=1

        -DWITH_BLACKHOLE_STORAGE_ENGINE=1

        -DWITH_FEDERATED_STORAGE_ENGINE=1

        

        若要明确指定不编译某存储引擎,可以使用类似如下的选项:

        -DWITHOUT__STORAGE_ENGINE=1

        比如:

        -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1

        -DWITHOUT_FEDERATED_STORAGE_ENGINE=1

        -DWITHOUT_PARTITION_STORAGE_ENGINE=1

        

        如若要编译进其它功能,如SSL等,则可使用类似如下选项来实现编译时使用某库或不使用某库:

        -DWITH_READLINE=1

        -DWITH_SSL=system

        -DWITH_ZLIB=system

        -DWITH_LIBWRAP=0

        

        其它常用的选项:

        -DMYSQL_TCP_PORT=3306

        -DMYSQL_UNIX_ADDR=/tmp/mysql.sock

        -DENABLED_LOCAL_INFILE=1

        -DEXTRA_CHARSETS=all

        -DDEFAULT_CHARSET=utf8

        -DDEFAULT_COLLATION=utf8_general_ci

        -DWITH_DEBUG=0

        -DENABLE_PROFILING=1

        

        如果想清理此前的编译所生成的文件,则需要使用如下命令:

        make clean

        rm CMakeCache.txt



    mariadb日志:

            查询日志:query log;

                    记录查询操作; 记录于文件file、表table;

                    general_log=on | off                    日志开启与否

                    log_output=file | table                日志保存格式

                    general_log_file=HOSTNAME.log       日志文件位置及名称

                    

            慢查询日志:slow query log;

                    执行时长超过指定时长的查询操作;long_query_time以秒为单位

                    slow_query_log=on | off

                    log_slow_queries

                    slow_query_log_file=HOSTNAME-slow.log

                    log_slow_filter=admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk      慢查询日志记录哪些内容

                    log_slow_rate_limit                    慢查询记录的速率

                    log_slow_verbosity                    慢查询记录的详细程度


            错误日志:error log;

                    记录mysqld启动和关闭过程中输出的事件信息、mysqld运行中产生的错误信息、event scheduler运行一个event时产生的日志信息、在主从复制架构中的从服务器上启动从                      服务器线程产生的信息;

                    log_error=/var/log/mariadb/mariadb.log

                    log_warnings=1 | 0            是否记录警告信息至错误日志文件中

 

            二进制日志:binary log;

                    记录导致数据改变或潜在导致数据改变的sql语句;

                    功能:用于通过“重放”日志文件中的事件来生成数据副本;

                    相关内置查询命令:

                            SHOW {BINARY | MASTER} LOGS       查看使用的二进制日志文件列表

                            SHOW MASTER STATUS                    查看正在使用中的二进制日志文件

                            SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]      查看具体二进制文件中的事件

                    二进制日志记录格式:

                            基于“语句”记录:statement

                            基于“行”记录:row

                            混合模式:mixed,让系统自行判定该基于哪种方式进行;

                    二进制日志文件构成:两类文件:

                            日志文件:mysql-bin.文件名后缀

                            索引文件:mysql-bin.index

                    服务器变量:

                            sql_log_bin=ON | OFF      是否记录二进制日志;

                            log_bin=/PATH/TO/BIN_LOG_FILE         二进制日志记录文件位置;建议设置为mysql-bin

                            binlog_format=STATEMENT                  二进制日志文件的格式

                            max_binlog_size           单个二进制日志文件的最大体积;默认为1G;注意:(1)到达最大值会自动滚动;(2)文件达到上限时的大小未必为精确值;

                            sync_binlog= 1 | 0               是否启用二进制日志同步功能;

                            expire_logs_days                多久自动删除

                    二进制日志查看命令:   mysqlbinlog [options] log_file ...



            中继日志:reley log;

                    复制架构中,从服务器用于保存从主服务器的二进制中读取到事件;                    

                    relay_log                    

                    relay_log_index                

                    relay_log_info_file        

                    relay_log_purge              

                    relay_log_recovery             

                    relay_log_space_limit         

                    sync_relay_log                

                    sync_relay_log_info        


            事务日志:transaction log;

                    事务型存储引擎自行管理和使用;

                    innodb_log_group_home_dir        事务日志文件位置

                    innodb_log_files_in_group            组内文件数量

                    innodb_log_file_size                     文件大小



        


            备份和恢复

                    数据备份一般备份:数据、二进制日志、innodb事务日志、服务器的配置文件、代码(存储过程、存储函数、触发器、事件调度器);

                    

                    备份:完全备份、增量备份、差异备份;

                            热备:读写操作均可进行;

                            温备:读操作可执行,但不可写操作;

                            冷备:读写操作均不可进行;


                    设计备份方案:

                            数据集:完全+增量;

                            备份手段:物理,逻辑;

                       

                    备份工具的选择:

                            mysqldump+复制binlog:

                                    mysqldump:完全备份;

                                    复制binlog中指定时间范围的event:增量备份;

                            lvm2快照+复制binlog:

                                    lvm2快照:使用cp或tar等做物理备份;完全备份;

                                    复制binlog中指定时间范围的event:增量备份;

                            xtrabackup:

                                    由percona提供的支持对innodb做热备份(物理备份)的工具;完全备份、增量备份;


                

                                    

                    逻辑备份工具:mysqldump、mydumper、phpMyAdmin

                        mysqldump:一般适用于G级别以下的备份;

                                   shell> mysqldump [options] db_name [tbl_name ...]         区别:不会创建数据库本身,只是备份数据库信息,还原时需自行创建该数据库;

                                   shell> mysqldump [options] --databases db_name ...

                                   shell> mysqldump [options] --all-databases


                            MyISAM引擎:支持温备:锁定备份库,而后启动备份操作;对innodb引擎的表一样生效,实现温备;

                                        锁定方法:

                                               --lock-all-tables:锁定所有库的所有表;

                                               --lock-tables:对于每个单独的数据库,在启动备份之前锁定所有表,非同时锁定所有库的所有表;


                            InnoDB:支持热备;

                                        --single-transaction


                            其他选项:

                                        -E,--events:备份指定数据库相关的所有event scheduler;

                                        -R,--routines:备份指定数据库相关的所有存储函数和存储过程;

                                        --triggers:备份表相关的触发器;

                                        --master-data=2:记录为注释的CHANGE MASTER TO语句;

                                        --flush-logs:锁定表完成后,执行flush logs命令;


                            注意:二进制日志文件不应该与数据文件放在同一磁盘;



            基于lvm2的数据库备份:

                        (1)请求锁定所有表:

                                    mysql>  flush tables with read lock;

                        (2)记录二进制日志文件及事件位置;

                                    mysql> flush logs;

                                    mysql -e  'show master status'   >   /root/pos.`date +%F`

                        (3)创建快照

                                    lvcreate -L 10G -s -n data-snap -p r    /dev/mydata/data

                        (4)释放全局锁;

                                    mysql>  unlock tables;

                        (5)挂载快照卷,执行数据备份;

                                    mount -r  /dev/mydata/data-snap /mnt

                                    cp   -a   /mnt/*   /tmp

                        (6)备份完成后,删除快照卷;

                        (7)制定好策略,通过原卷备份二进制日志(建议备份前滚动下二进制日志);

                                    


            基于lvm2的数据库还原:

                        (1)建议还原前临时关闭二进制日志:

                                    mysql> SET sql_bin_log=0;

                        (2)恢复数据库文件,除二进制日志文件;

                                    cp  -a /tmp/mysql/*     /data/mysql

                        (3)启动数据库,并查找对应的二进制日志文件的记录位置,进行选择性重放;

                                    systemctl start mariadb

                                    cat /root/pos            查看得知具体position

                                    mysqlbinlog    --start-position=245   mysql-bin.000004



            xtrabackup备份:最小权限的备份用户只需拥有reload,lock tables,replication client权限即可;

                        注意:仅对innodb引擎支持完全、增量备份,且很多功能需要开启innodb_file_per_table;

                        1、完全备份;BASEDIR为完全备份路径;

                                innobackupex    --user=DBUSER    --password=SECRET     BASEDIR

                        

                        2、增量备份;需指明针对一个完全备份或者增量备份做备份;即--incremental-basedir

                                innobackupex    --user=DBUSER    --password=SECRET    --incremental    /backup   --incremental-basedir=BASEDIR 


                        3、还原备份步骤:

                                a、准备(prepare),需合并增量到完全备份上,先合并第一个增量,然后递归一直到最后一个;BASEDIR为完全备份路径;

                                        innobackupex     --apply-log    --redo-only     BASEDIR

                                        innobackupex     --apply-log    --redo-only     BASEDIR   --incremental-dir=INCREMENTAL-DIR-1

                                        innobackupex     --apply-log    --redo-only     BASEDIR   --incremental-dir=INCREMENTAL-DIR-2        ......

                                b、停止mysql,并还原备份

                                        systemctl    stop   mariadb

                                        innobackupex     --copy-back    /path/to/backup/dir

                                c、确保数据库文件属主属组正确,并启动数据库

                                       

            


            mysql主从复制架构:

                    复制的功用:

                        数据分布

                        负载均衡

                        备份

                        高可用和故障切换

                        mysql升级测试

                

            主从复制:

                        从节点:

                                I/O  thread:从master请求二进制日志事件,并保存于中继日志中:

                                SQL thread:从中继日志中读取日志事件,在本地完成重发;


                        主节点:

                                DUMP thread:为每个slave的I/O thread启动一个dump线程,用于向其发送二进制日志事件;


                        特点:

                                1、异步复制;

                                2、主从数据不一致比较常见;

                    

                        复制架构:

                                M/S,M/M

                                一主多从:从服务器还可以再有从服务器;


                        二进制日志事件格式:

                                statement、row、mixed


           主从复制配置:

                    主节点:

                            (1)启动二进制日志;

                                    # vim /etc/my.cnf

                                        log_bin=master-bin

                            (2)为当前节点设置一个全局唯一的ID号;

                                        server_id=1

                            (3)创建有复制权限(replication slave、replication client)的用户账号;

                                    # systemctl start mariadb

                                    # mysql -uroot -p

                                    mysql> grant replication slave,replication client on *.*  to 'repluser'@'172.20.120.%'  identified by 'replpass';

                                    mysql> flush privileges;

                    从节点:

                            (1)启动中继日志;

                                    # vim /etc/my.cnf

                                        relay_log=relay-log

                                        relay_log_index=relay_log.index

                            (2)为当前节点设置一个全局唯一的ID号;

                                        server_id=3

                            (3)使用有复制权限的用户账号连接至主服务器,并启动复制线程;

                                    # mysql -uroot -p

                                    mysql> change master to master_host='172.20.120.10',master_user='repluser',master_password='replpass', master_log_file='master-bin.000003',master_log_pos=245;

                                    mysql> start slave;

                                    查看slave信息:mysql> show slave status\G;

                                    

                 复制架构中应该注意的问题:

                            1、限制从服务器为只读;read_only=ON;此限制对拥有super权限的用户均无效;

                                    阻止所有用户:mysql> flush tables with read lock; 

                            2、如何保证主从复制的事务安全?

                                    在master节点启用参数:sync_binlog=ON、sync_master_info=ON

                                        如果用到的为innodb存储引擎:

                                            innodb_flush_logs_at_trx_commit=ON

                                            innodb_support_xa=ON

                                    在slave节点启用参数:skip_slave_start=ON、sync_relay_log=ON、sync_relay_log_info=ON


                如果主节点已经运行一段时间,且有大量数据时,如何配置并启动从节点?

                    1、通过备份恢复数据到从服务器;

                    2、复制起始位置为备份时的二进制日志文件及其pos。即

                                    mysql> change master to master_host='172.20.120.10',master_user='repluser',master_password='replpass', master_log_file='master-bin.000003',master_log_pos=245;

                                    mysql> start slave;

                                                                        

           主主复制配置:

                互为主从:

                    1、数据不一致:因此,慎用;

                    2、自动增长id:

                            配置一个节点使用奇数id,auto_increment_offset=1,auto_increment_increment=2

                            另一节点使用偶数id,auto_increment_offset=2,auto_increment_increment=2

                配置步骤:

                    1、各节点使用一个唯一server_id;

                    2、都启用log_bin和relay_log;

                    3、都得创建拥有复制权限(replication slave、replication client)的用户账号;

                    4、自定义自动增长id;

                    5、均把对方指定为主节点,并启动复制线程;


               半同步复制     相关查看命令:show global variables like '%semi%';      show global status like '%semi%';

                   master:

                        1、mysql> install  plugin rpl_semi_sync_master soname 'semisync_master.so';

                        2、mysql> set global variables rpl_semi_sync_master_enabled=1; 

                             mysql> start slave;

                   slave:

                       1、mysql> install  plugin rpl_semi_sync_slave soname 'semisync_slave.so';      

                       2、mysql> set global variables rpl_semi_sync_slave_enabled=1; 

                            mysql> start slave;                


            复制过滤器:

                        让从节点仅复制指定的数据库,或指定数据库的指定表;

                有两种实现方式:

                        1、主服务器仅向二进制日志中记录与特定数据库(特定表)相关的事件; 

                                问题:时间点还原无法实现,不建议使用;

                                具体实施方案:

                                binlog_do_db=                  :数据库白名单列表,逗号隔开  

                                binlog_ignore_db=                  :数据库黑名单列表,逗号隔开           

                        2、从服务器SQL_THREAD在replay中继日志中的事件时,仅读取特定的数据库(特定表)相关的事件并应用于本地;

                                问题:会造成网络及磁盘IO浪费;

                                具体实施方案:

                                replicate_do_db=

                                replicate_ignore_db=

                                replicate_do_table=

                                replicate_ignore_table=

                                replicate_wild_do_table=

                                replicate_wild_ignore_table=



            基于ssl复制:

                        前提:支持ssl;

                        (1)master端配置证书和私钥:并且创建一个要求必须使用ssl连接的复制账号;

                                    grant replication slave,replication client on *.*  to 'repluser'@'172.20.120.%'  identified by 'replpass' require ssl;

                        (2)slave端使用change master to 命令时指明ssl相关选项;                                        


                

            跟复制功能相关的文件:

                        master.info:用于保存slave连接至master时的相关信息;例如账号、密码、服务器地址等等;

                        relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地replay log日志的对应关系;


            复制的监控和维护:

                        (1)清理日志:请保证已备份;

                                MySQL>   purge binary log to  'mysql-bin.000002';             清理具体某个二进制日志之前的所有

                                MySQL>   purge binary log before '2018-04-12 10:00:00';

                        (2)复制监控;

                                MySQL>   show master status;

                                MySQL>   show binlog events;

                                MySQL>   show binary logs;

                                MySQL>   show slave status;

                                MySQL>   show processlist;

                        (3)从服务器是否落后于主服务器;

                                从服务器:MySQL>   show slave status;      ----------> Seconds_Behind_Master: 0     具体查看指标

                        (4)如何确定主从节点数据是否一致;

                                安装percona-tools包

                        (5)数据不一致如何修复;

                                确定以主节点为准,重新复制;


            


            

            mysql分布式系统:

                    cap:一致性,可用性、网络分区容错性;      


                    切分:cobar、gizzard

                        1、垂直切分:俗称分库;

                        2、水平切分: 分表,sharding                                 


            主节点高可用方案:

                    MMM:多主

                    MHA:master HA:通过对主节点进行监控,可实现自动故障转移至其他从节点;通过提升某一从节点为新的主节点;

                    galera cluster:wresp;通过wresp协议,在全局实现复制,任何一节点都可读写;        

                   

                    高可用mysql常见方案:

                                heartbeat+drbd

                                mysql cluster

                                半同步复制

                                全局事务ID




                    MHA:master HA:开源的mysql的高可用程序;为mysql主从复制架构提供automating master failover功能;

                                MHA服务的两种角色:

                                        MHA manager:通常单独部署在一个独立机器上管理多个master/slave集群;

                                        MHA node:运行在每台mysql服务器上(master/slave/manager),通过监控具备解析和清理logs功能的脚本来加快故障转移;



                    MHA环境中主机ssh互信:

                                ssh-keygen -t rsa -P ''

                                cat .ssh/id_rsa.pub >>  .ssh/authorized_keys

                                chmod 600   .ssh/authorized_keys

                                scp -p  .ssh/id_rsa   .ssh/authorized_keys     node2:/root/.ssh

                                scp -p  .ssh/id_rsa   .ssh/authorized_keys     node3:/root/.ssh

                                scp -p  .ssh/id_rsa   .ssh/authorized_keys     node4:/root/.ssh


                    MHA配置文件:

                                global配置,为各application提供默认配置;

                                application配置:

                                        server


                    centos7下mha环境搭建:

                                mha4mySQL-manager和mha4mysql-node    
                                       https://github.com/yoshinorim/mha4mysql-manager
                                       https://github.com/yoshinorim/mha4mysql-node

                                使用版本分别是:mha4mysql-manager-0.58-0.el7.centos.noarch.rpm、mha4mysql-node-0.58-0.el7.centos.noarch.rpm

                    步骤:

                            1:MHA环境中主机ssh互信;

                            2:搭建好mysql的主从复制;

                            3:配置好配置文件;


                    具体操作可查阅马哥教育的MHA.PDF文档;



            复制的问题和解决方案:

                    1、数据损坏或丢失:

                            master:MHA + SEMI repl(半同步复制)

                            slave:重新复制

                    2、混合使用存储引擎:

                            myisam:不支持事务

                            innodb:支持事务

                    3、不唯一的server id

                            重新复制

                    4、复制延迟

                           需要额外的监控工具辅助

                      

 

           数据库服务衡量指标:测试工具:sysbench  

                    qps:query per second:每秒查询量                          

                                use information_schema;

                                select VARIABLE_VALUE into @num_queries from GLOBAL_STATUS where VARIABLE_NAME ='QUESTIONS';

                                select VARIABLE_VALUE into @uptime from GLOBAL_STATUS where VARIABLE_NAME ='UPTIME';

                                select @num_queries/@uptime;


                    tps:transaction per second:每秒事务量                               

                                use information_schema;

                                select VARIABLE_VALUE into @num_com from GLOBAL_STATUS where VARIABLE_NAME ='COM_COMMIT';

                                select VARIABLE_VALUE into @num_roll from GLOBAL_STATUS where VARIABLE_NAME ='COM_ROLLBACK';

                                select VARIABLE_VALUE into @uptime from GLOBAL_STATUS where VARIABLE_NAME ='UPTIME';

                                select (@num_com+@num_roll)/@uptime;


            基于galera cluster构建多主模型的复制集群:无需前端动静分离,可直接负载均衡即可;动静分离(mysql-proxy等目前不成熟),很多时候需自研工具;

                    wresp协议;                    

                        percona-cluster

                        mariadb-cluster:对应的软件由https://downloads.mariadb.org官网提供下载                    

                                优点:网络状态可用情况下,节点间基本实时数据同步,完胜MHA的日志可能不同步;

                                特点:分担读操作,前端没必要读写分离、只需做负载均衡即可。

                                条件:1、至少要三个节点;2、不能安装mariadb-server。

                                配置文件参数解释:注意配置文件需节点都设置;

                                # cat /etc/my.cnf.d/server.cnf

                                [galera]

                                # Mandatory settings

                                wsrep_provider= "/usr/lib64/galera/libgalera_smm.so"#插件;

                                wsrep_cluster_address="gcomm://172.20.120.67,172.20.120.68,172.20.120.69"

                                wsrep_cluster_name=my_galera_cluster

                                #wsrep_node_address=#节点地址,可省略;

                                #wsrep_node_name=#节点名,可省略;

                                binlog_format=row#二进制日志格式;

                                default_storage_engine=InnoDB

                                innodb_autoinc_lock_mode=2#锁格式;

                                bind-address=0.0.0.0#工作时监听的地址;

                                

                                首次启动时,需要初始化集群,在其中任意节点上执行如下命令:

                                /etc/init.d/mysql start --wsrep-new-cluster [--wsrep_cluster_name=my_galera_cluster]

                                

                                而后正常启动其他节点:

                                /etc/init.d/mysql start

                                                        

                    


            中间件实现mysql读写分离:                        

                    mysql-proxy----->atlas(奇虎)

                    amoeba