《高性能mysql》第三版

第一章 mysql架构与历史

逻辑架构:

第一层:链接/线程处理,比如连接处理,授权认证,安全等等;

第二层:查询解析,分析,优化,缓存以及所有的内置函数(例如:日期,时间)。

第三层:包含存储引擎,负责mysql中的数据存储和提取

锁:共享锁和排它锁(读锁和写锁)

锁粒度:表锁,行锁

事务(ACID)

原子性(atomicity):不可分割的最小单元,全部成功或者全部失败;

一致性(consistency)

隔离性(isolation):一个事务所做的修改在最终提交之前对其他事务不可见

持久性(durability):数据提交永久保存在数据库中

隔离级别 (参考链接:)

设置隔离级别:set transaction isolatton level 【级别名】

未提交读(read uncommitted):脏读,事务中的修改,即使没有提交,对其他事务也是可见的

提交读(read committed):不可重复读,满足事务的隔离性要求;

可重复读(repeatable read):可重复读是mysql默认事务隔离级别,解决了脏读问题无法解决幻读(事务在读取某个范围内的记录时,另一个事务又在该返回插入了新的数据,再次读取产生幻行)

可串行化(serializable)

死锁:多个事务在同一资源上相互占用并请求锁定了对方的资源,从而导致事务一直无法提交

start transaction;                                                            update user set coin = coin - 100 where id = 1;                              update user set coin = coin + 100 where id = 2;                               commit;                                                              

start transaction;                                                            update user set coin = coin - 100 where id = 2;                              update user set coin = coin + 100 where id = 1;                               commit; 

选择存储引擎

事务:是否需要支持事务;

备份:是否需要在线热备;

崩溃恢复

特有的特性

mongodb 语法

1.查看数据库列表  show dbs

2.切换数据库 (mongodb会在需要的时候自动创建数据库)

3.删除数据库

4.插入数据  db.{数据表名}.insert()

5.查询 db.{数据表名}.find(查询条件)     findOne  查询单条

6.统计符合结果集的条数 db.{数据表名}.count()

7.连贯操作

db.test_collection.find().limit(4).sort({“name”:1}).skip(2)

查询 test_collection 表 结果集限制输出4条  按照 name 属性排序   跳过前两 2条

8.更新操作 db.test_collection.update(更新条件,更新的结果数据,true)

第三个参数  表示更新条件的数据不存在时自动插入一条

第四个参数表示是否更新所有满足条件的行

db.test_collection.update({“name”:1},{$set:”name”:666})     加上参数只更新指定的参数

8.删除指定的数据

9.查看表 show tables  删除表 db.{表名}.drop()

10.查看表拥有的索引 db.{表名}.getIndexes()

11.创建索引  db.{表名}.ensureIndex(“name”:1)  1 为正序 -1 为倒序

修改PHP上传文件大小限制的方法

修改PHP上传文件大小限制的方法
1. 一般的文件上传,除非文件很小.就像一个5M的文件,很可能要超过一分钟才能上传完.
但在php中,默认的该页最久执行时间为 30 秒.就是说超过30秒,该脚本就停止执行.
这就导致出现 无法打开网页的情况.这时我们可以修改 max_execution_time
在php.ini里查找
max_execution_time
默认是30秒.改为
max_execution_time = 0
0表示没有限制
2. 修改 post_max_size 设定 POST 数据所允许的最大大小。此设定也影响到文件上传。
php默认的post_max_size 为2M.如果 POST 数据尺寸大于 post_max_size $_POST 和 $_FILES superglobals 便会为空.
查找 post_max_size .改为
post_max_size = 150M
3. 很多人都会改了第二步.但上传文件时最大仍然为 8M.
为什么呢.我们还要改一个参数upload_max_filesize 表示所上传的文件的最大大小。
查找upload_max_filesize,默认为8M改为
upload_max_filesize = 100M
另外要说明的是,post_max_size 大于 upload_max_filesize 为佳.

;还需要根据实际情况调整下面的选项
max_execution_time = 180 ;脚本最大执行时间(秒) ,过短会导致文件还没上传完脚本就停止了。
max_input_time = 180 ;请求的最大传输时间,过短会导致文件还没上传完传输就停止了。
memory_limit = 128M ;内存上限

修改完成后重启php-fpm或reload配置。

 

 

 

Nginx配置更改

如果上传文件时超过了nginx的限制,就会返回一个“413 Request Entity Too Large”的错误。
我们只要更改nginx的配置文件“nginx.conf”即可。
在http{}中添加一个client_max_body_size 20m;配置项;
修改完成之后重启nginx或reload配置。

mysql 备份(xtrabackup)

安装xtrabackup

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm

yum -y install percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm

备份

innobackupex --user=root --password=test /data/backup/

innobackupex 参数选项

–defaults-file=[MY.CNF]    //指定配置文件:只能从给定的文件中读取默认选项。 且必须作为命令行上的第一个选项;必须是一个真实的文件,它不能是一个符号链接。

–databases=#    //指定备份的数据库和表,格式为:–database=”db1[.tb1] db2[.tb2]” 多个库之间以空格隔开,如果此选项不被指定,将会备份所有的数据库。

–include=REGEXP    //用正则表达式的方式指定要备份的数据库和表,格式为 –include=‘^mydb[.]mytb’ ,对每个库中的每个表逐一匹配,因此会创建所有的库,不过是空的目录。–include 传递给 xtrabackup –tables。

–tables-file=FILE    //此选项的参数需要是一个文件名,此文件中每行包含一个要备份的表的完整名称,格式为databasename.tablename。该选项传递给 xtrabackup –tables-file,与–tables选项不同,只有要备份的表的库才会被创建。

注意:部分备份(–include、–tables-file、–database)需要开启 innodb_file_per_table 。

–compact    //创建紧凑型备份,忽略所有辅助索引页,只备份data page;通过–apply-log中重建索引–rebuild-indexs。

–compress    //此选项指示xtrabackup压缩备份的InnoDB数据文件,会生成 *.qp 文件。

–decompress    //解压缩qp文件,为了解压缩,必须安装 qpress 工具。 Percona XtraBackup不会自动删除压缩文件,为了清理备份目录,用户应手动删除 * .qp文件:find /data/backup -name “*.qp” | xargs rm。

–no-timestamp    //指定了这个选项备份将会直接存储在 BACKUP-DIR 目录,不再创建时间戳文件夹。

–apply-log    //应用 BACKUP-DIR 中的 xtrabackup_logfile 事务日志文件。一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处于不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件使得数据文件处于一致性状态。

–use-memory=#    //此选项接受一个字符参数(1M/1MB,1G/1GB,默认100M),仅与–apply-log一起使用,该选项指定prepare时用于崩溃恢复(crash-recovery)的内存。

–copy-back    //拷贝先前备份所有文件到它们的原始路径。但原路径下不能有任何文件或目录,除非指定 –force-non-empty-directories 选项。

–force-non-empty-directories    //恢复时指定此选项,可使 –copy-back 和 –move-back 复制文件到非空目录,即原data目录下可以有其他文件,但是不能有与恢复文件中同名的文件,否则恢复失败。

–rsync    //此选项可优化本地文件(非InnoDB)的传输。rsync工具一次性拷贝所有非InnoDB文件,而不是为每个文件单独创建cp,在备份恢复很多数据库和表时非常高效。此选项不能和 –stream 一起使用。

–incremental    //这个选项告诉 xtrabackup 创建一个增量备份,而不是完全备份。它传递到 xtrabackup 子进程。当指定这个选项,可以设置 –incremental-lsn 或 –incremental-basedir。如果这2个选项都没有被指定,–incremental-basedir 传递给 xtrabackup 默认值,默认值为:基础备份目录的第一个时间戳备份目录。

–incremental-basedir=DIRECTORY    //该选项接受一个字符串参数,该参数指定作为增量备份的基本数据集的完整备份目录。它与 –incremental 一起使用。

–incremental-dir=DIRECTORY    //该选项接受一个字符串参数,该参数指定了增量备份将与完整备份相结合的目录,以便进行新的完整备份。它与 –incremental 选项一起使用。

–redo-only    //在“准备基本完整备份” 和 “合并所有的增量备份(除了最后一个增备)”时使用此选项。它直接传递给xtrabackup的 xtrabackup –apply-log-only 选项,使xtrabackup跳过”undo”阶段,只做”redo”操作。如果后面还有增量备份应用到这个全备,这是必要的。有关详细信息,请参阅xtrabackup文档。

–parallel=NUMBER-OF-THREADS    //此选项接受一个整数参数,指定xtrabackup子进程应用于同时备份文件的线程数。请注意,此选项仅适用于文件级别,也就是说,如果您有多个.ibd文件,则它们将被并行复制; 如果您的表一起存储在一个表空间文件中,它将不起作用。

2) xtrabackup 参数选项

–apply-log-only    //这个选项使在准备备份(prepare)时,只执行重做(redo)阶段,这对于增量备份非常重要。

参考链接:https://www.cnblogs.com/waynechou/p/xtrabackup_backup.html

mysql 服务器性能剖析

1.理解性能剖析

  • 值得优化的查询:一些占总响应时间比重很小的查询是不值得优化的
  • 异常情况:某些任务执行次数很少,但每次执行都很慢

long_query_time 慢查询日志响应时间

2.分析查询日志(pt-query-digest)

安装:yum install -y perl-CPAN perl-Time-HiRes

wget https://www.percona.com/downloads/percona-toolkit/3.0.11/binary/redhat/7/x86_64/percona-toolkit-3.0.11-1.el7.x86_64.rpm

yum -y install percona-toolkit-3.0.11-1.el7.x86_64.rpm

参考链接:https://www.cnblogs.com/luyucheng/p/6265873.html

工具:performance schema    http://www.cnblogs.com/cchust/p/5061131.html

3.schema和数据类型优化

选择优化的数据类型

  • 更小的通常更好:更小的数据类型通常更快,因为他们占用更少的磁盘、内存和cpu缓存,并且处理时需要的cpu周期也更少
  • 简单就好:简单数据类型通常需要更少的cpu周期。例如:整型比字符串操作代价更低,因为字符集和排序规则使字符比较整型比较更复杂。
  • 尽量避免null:若果查询中包含null的列,对mysql来说更难优化,因为可为null的列使的索引、索引统计和值比较更为复杂。

整数类型:为整数类型指定宽度,例如:int(2),对于存储int(1)和int(10)是相同的;

存储货币:根据小数位乘以相应的倍数,例如:12.02元 = 1202分

字符串类型

varchar:使用1个或2个额外字节记录字符串长度。适合使用varchar存储,字符串列长度比平均值长很多,列很少更新,复杂的字符集(utf8)

char:适合存储短的字符串或者所有值都很相近的,例如MD5值

关联表时字段类型最好相同,包含unsigned这样的属性

spring boot aop

AOP 使用

使用步骤

  • 在pom.xml 文件增加 spring-boot-starter-aop 依赖,默认已经开启
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
  • 编写Aspect 封装横切关注点(日志,监控等)
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {

    @Before("execution(* com.pcg.wx1.dao..*.*(..))")
    public void log(){
        System.out.println("切面打印日志中...");
    }
}
  • Aspect 需要纳入到 spring 容器管理 (加入 @Aspect 和 @Component 注解)

Beanstalkd消息队列的安装与使用

Beanstalkd消息队列的安装与使用

一、Beanstalkd是什么?

Beanstalkd是一个高性能,轻量级的分布式内存队列

 

二、Beanstalkd特性

1、支持优先级(支持任务插队)
2、延迟(实现定时任务)
3、持久化(定时把内存中的数据刷到binlog日志)
4、预留(把任务设置成预留,消费者无法取出任务,等某个合适时机再拿出来处理)
5、任务超时重发(消费者必须在指定时间内处理任务,如果没有则认为任务失败,重新进入队列)

 

三、Beanstalkd核心元素

生产者 -> 管道(tube) -> 任务(job) -> 消费者

Beanstalkd可以创建多个管道,管道里面存了很多任务,消费者从管道中取出任务进行处理。

 

四、任务job状态

delayed 延迟状态
ready 准备好状态
reserved 消费者把任务读出来,处理时
buried 预留状态
delete 删除状态

五、安装Beanstalkd

1
http://kr.github.io/beanstalkd/download.html

下载beanstalkd-1.10.tar.gz

1
2
3
> tar -xf beanstalkd-1.10.tar.gz
> cd beanstalkd-1.10
> make

查看beanstalkd参数信息

1
> ./beanstalkd -h

启动beanstalkd

1
> ./beanstalkd -l 127.0.0.1 -p 11300 -b /data/beanstalkd/binlog &

-b表示开启binlog,断电后重启自动恢复任务

/data/beanstalkd/binlog  为目录

 

六、下载Pheanstalk类

首先安装composer

1
2
3
> curl -sS https://getcomposer.org/installer | php
> mv composer.phar /usr/local/bin/composer
> composer require pda/pheanstalk

编写一个简单脚本查看信息

1
2
3
4
5
6
7
8
<?php
require './vendor/autoload.php';
use Pheanstalk\Pheanstalk;
$p new Pheanstalk('127.0.0.1', 11300);
//查看beanstalkd当前的状态信息
var_dump($p->stats());

 

七、Pheanstalk使用方法

维护方法

1
2
3
4
5
6
7
stats() 查看状态方法
listTubes() 目前存在的管道
listTubesWatched() 目前监听的管道
statsTube() 管道的状态
useTube() 指定使用的管道
statsJob() 查看任务的详细信息
peek() 通过任务ID获取任务

生产者方法

1
2
putInTube() 往管道中写入数据
put() 配合useTube()使用

消费者方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
watch() 监听管道,可以同时监听多个管道
ignore() 不监听管道
reserve() 以阻塞方式监听管道,获取任务
reserveFromTube()
release() 把任务重新放回管道
bury() 把任务预留
peekBuried() 把预留任务读取出来
kickJob() 把buried状态的任务设置成ready
kick() 批量把buried状态的任务设置成ready
peekReady() 把准备好的任务读取出来
peekDelayed() 把延迟的任务读取出来
pauseTube() 给管道设置延迟
resumeTube() 取消管道延迟
touch() 让任务重新计算ttr时间,给任务续命

生产者producer.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
require './vendor/autoload.php';
use Pheanstalk\Pheanstalk;
//创建一个Pheanstalk对象
$p new Pheanstalk('192.168.1.222', 11300);
$data array(
    'id' => 1,
    'name' => 'test',
);
//向userReg管道中添加任务,返回任务ID
//put()方法有四个参数
//第一个任务的数据
//第二个任务的优先级,值越小,越先处理
//第三个任务的延迟
//第四个任务的ttr超时时间
$id $p->useTube('userReg')->put(json_encode($data));
//获取任务
$job $p->peek($id);
//查看任务状态
print_r($p->statsJob($job));

消费者consumer.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
require './vendor/autoload.php';
use Pheanstalk\Pheanstalk;
//创建一个Pheanstalk对象
$p new Pheanstalk('192.168.1.222', 11300);
//监听userReg管道,忽略default管道
$job $p->watch('userReg')->ignore('default')->reserve();
$data = json_decode($job->getData());
//打印任务中的数据
print_r($data);
//最后删除任务,表示任务处理完成
$p->delete($job);

linux shell script

#!/bin/bash  
############################
#desc:这只是练习案例
############################

read -t 10 -p '请输入你的名字: ' name;  #name变量提示用户输入,用户10秒未      输入结束

name=${name:- 'ace'}; #当name未定义时默认值为ace

1.判断

-e : 该文件名是否存在(目录或文件)

-f : 该文件是否存在

-d : 该目录是否存在

-r : 该文件是否具有读权限

-w : 该文件是否具有写权限

-x : 该文件是否具有执行权限

-eq : 两个值是否相等

-gt -lt : 大于,小于

== : 判断两个字符串是否相等

-a : and 相当于 &&

-o : or 相当于 ||

-! :  取反