php中处理emoji符号

数据库表是utf8编码的, 所以在存储emoji符号的时候,直接报错,可使用以下方法:

http://stackoverflow.com/questions/12807176/php-writing-a-simple-removeemoji-function#

有时候这种方法不行,可以使用以下方法

/**
  把用户输入的文本转义(主要针对特殊符号和emoji表情)
 */
function userTextEncode($str){
    if(!is_string($str))return $str;
    if(!$str || $str=='undefined')return '';

    $text = json_encode($str); //暴露出unicode
    $text = preg_replace_callback("/(\\\u[ed][0-9a-f]{3})/i",function($str){
        return addslashes($str[0]);
    },$text); //将emoji的unicode留下,其他不动,这里的正则比原答案增加了d,因为我发现我很多emoji实际上是\ud开头的,反而暂时没发现有\ue开头。
    return json_decode($text);
}
/**
  解码上面的转义
 */
function userTextDecode($str){
    $text = json_encode($str); //暴露出unicode
    $text = preg_replace_callback('/\\\\\\\\/i',function($str){
        return '\\';
    },$text); //将两条斜杠变成一条,其他不动
    return json_decode($text);
}

当然你也可以直接将emoji之类的字符直接过滤掉,存储到数据库中。只需要将 "return addslashes($str[0]); “修改为 reuturn ''即可.

参考:https://segmentfault.com/q/1010000003711491

查看InnoDB的磁盘空间利用率

这周阿里集团DBA内部分享时,支付宝的黄忠同学提了一个问题,关于InnoDB索引page 的利用率。

page利用率

主要是指btee里面每个page的使用被使用的空间大小。我们知道InnoDB默认一个page大小是16k。但实际使用情况不会总用满

我们定义为所有page的总使用字节除以总字节数。

在理论分析之前,我们要先弄个工具,查一下。

Continue reading

关于InnoDB表的page利用率和optimize table

上一篇我们介绍了ibd_used这个工具,我们用来量化看表数据文件的page使用率。这里用来说明optimize table这个命令的问题和优化。

实例准备

建一个这样的表

CREATE TABLE `tb` (

`seq_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,

`a` varchar(32) DEFAULT NULL,

`b` varchar(32) DEFAULT NULL,

`c` varchar(32) DEFAULT NULL,

`d` char(255) DEFAULT NULL,

Primary key (seq_id),
KEY a (a),

KEY bc (b,c),

KEY cb (c,b)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

执行语句为“insert into tb(a,b,c) values(randstr, randstr, randstr);” randstr是客户端程序生成的长度30字节的随机字符串。30个线程并发,每个线程插入1w条记录。

等待更新完成后(包括purge完成,从系统的vmstat上看无任何io),执行./ibd_used tb.ibd 0 100000000,可以从最后4行看到各个索引的page平均利用率如下图。

说明: 你会发现即使是主键索引,利用率也不一定很高。原因是什么?

Optimize table 效果

我们知道Optimize table是用来作表整理的, 执行一下 optimize table tb,再看ibd_used的结果。 Continue reading

关于 InnoDB 索引长度限制的 tips

有同学问到InnoDB的索引长度问题,简单说几个tips。

关于3072

大家经常碰到InnoDB单列索引长度不能超过767bytes,实际上联合索引还有一个限制是3072。

可以看到,由于每个字段占用255*3, 因此这个索引的大小是3825(255*3*5)>3072,报错。

为什么3072

我们知道InnoDB一个page的默认大小是16k。由于是Btree组织,要求叶子节点上一个page至少要包含两条记录(否则就退化链表了)。 Continue reading

传统复制与 GTID复制的切换知识点

在5.6以后,可以通过命令动态修改.

注意有些命令是需要主从都要执行,有些命令是只在slave执行。

gtid_mode 的几种状态值说明:
OFF: 不产生 GTID, 基于 binlog+position,也不能接受GTID的日志。默认值
OFF_PERMISSIVE:  不生产 GTID,但作为slave可以识别GTID事务也可以识别非GTID事务
ON_PERMISSIVE: 产生GTID,slave可以处理GTID事务和非GTID事务
ON: 产生GTID事务,slave只接受GTID事务

实验一:将传统复制切换到GTID复制

启用GTID:

set @@global.enforce_gtid_consitency=warn;
set @@global.enforce_gtid_consistency=on;
set @@global.gtid_mode=OFF_PERMISSIVE; #不产生gtid,但可以处理gtid
set @@global.gtid_mode=ON_PERMISSIVE; #产生gtid,也可以处理gtid
show status like 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
set @@global.gtid_ode=on;

stop slave [for channel 'channel'];change master to master_auto_postion=1; start slave;(slave)

更改复制到自动识别GTID环境 Continue reading

5.7半同步复制

在5.7下半同步是以插件的形式出现的,所以在启用半同步前要先安装半同步插件 semisync_master.so

On the master:

INSTALL PLUGIN rpl_remi_sync_master SONAME 'semisync_master.so';

On slave slave:

INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

在my.cnf里配置,要写在mysqld段

master:

[mysqld]
repl_semi_sync_master_enable=1
repl_semi_sync_master_timeout=1000 #1 second

slave:

[mysqld]

repl_semi_sync_slave_enable=1

卸载插件:

uninstall plugin rpl_semi_sync_master;#master
uninstall plugin rpl_semi_sync_slave; #slave

在主上设置slave的数量,用来接受slave返回的次数数量2,用来分析 show global variables like '%semi%';

set global rpl_semi_sync_master_wait_for_slave_count=2;

监控:

show global status like 'rpl_semi_sync%';