August 28, 2018
[译]Go里面的unsafe包详解
"\u003cp\u003eunsafe包位置: \u003ccode\u003esrc/unsafe/unsafe.go\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e指针类型:\u003c/strong\u003e\n***类型:**普通指针,用于传递对象地址,不能进行指针运算。\n**unsafe.Pointer:**通用指针,用于转换不同类型的指针,不能进行指针运算。\n**uintptr:**用于指针运算,GC 不把 uintptr 当指针,uintptr 无法持有对象。uintptr 类型的目标会被 GC 回收。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eunsafe.Pointer 可以和 普通指针 进行相互转换。\nunsafe.Pointer 可以和 uintptr 进行相互转换。\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e也就是说 unsafe.Pointer 是桥梁,可以让任意类型的指针实现相互转换,也可以将任意类型的指针转换为 uintptr 进行指针运算。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e一般使用流程:\u003c/strong\u003e\n第一步:将结构体 -\u0026gt; 通用指针unsafe.Pointer(struct) -\u0026gt; uintptr(通用指针)获取内存段的起始位置start_pos,并记录下来,第二步使用。\n第二步:使用start_pos + unsafe.Offsetof(s.b) -\u0026gt; 将地址转为能用指 …\u003c/p\u003e"
August 28, 2018
golang中slice切片理解总结
"\u003cp\u003e首先我们对切片有一个大概的理解,先看一下slice的内部结构,共分三部分,一个是指向底层数组的时候,一个是长度len,另一个就是slice的容量cap了。如cap不足以放在新值的时候,会产生新的内存地址申请。\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://blog--static.oss-cn-shanghai.aliyuncs.com//uploads/2023/09/image-20230904182516517.png\" alt=\"image-20230904182516517\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://blog--static.oss-cn-shanghai.aliyuncs.com//uploads/2023/09/image-20230904182527333.png\" alt=\"image-20230904182527333\"\u003e\u003c/p\u003e\n\u003cp\u003e先看代码\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003epackage main\n\nimport \u0026#34;fmt\u0026#34;\n\nfunc main() {\n\n // 创建一个切片,长度为9,容量为10\n fmt.Println(\u0026#34;----- 1.测试切片变量append的影响(未申请新的内存空间)-----\u0026#34;)\n a := make([]int, 9,10)\n fmt.Printf( \u0026#34;%p len=%d cap=%d %vn\u0026#34; , a, len(a), cap(a), a)\n\n // 切片进行append操作,由于原来len(a)长度为9,而cap(a)容量为10,未达到扩展内存的要求,此时新创建的切片变量还指向原来的底层数组,只是数组的后面添加一个新值\n // 此时一共两个切片变量,一个是a,另一个是s4。但共指向的一个内存地址\n s4 := …\u003c/code\u003e\u003c/pre\u003e"
August 20, 2018
MySQL中的innodb_file_format 配置项解读
"\u003ch2 id=\"一innodb_file_format参数\"\u003e一:innodb_file_format参数\u003c/h2\u003e\n\u003cp\u003e在 innodb 1.0.6版本之前,innodb文件格式\u003ccode\u003einnodb_file_format\u003c/code\u003e只有 Antelope(Antelope 文件格式支持Redundant,Compact两种格式来存放行记录,Redundant是为了兼容之前版本而保留的。在mysql 5.1版本中,默认设置为Compact,用户可以通过 \u003ccode\u003eshow table status like 'table_name'\u003c/code\u003e来查看表使用的行格式row_format)\u003c/p\u003e\n\u003cp\u003e从innodb 1.0.6开始引入了新的文件格式 Barracuda 在原来的基础上(Antelope)新增了Dynamic和Compressed两种行格式。\u003c/p\u003e\n\u003ch2 id=\"二innodb_file_format如何使用\"\u003e二:innodb_file_format如何使用\u003c/h2\u003e\n\u003cp\u003e 一般, \u003ccode\u003einnodb_file_format\u003c/code\u003e 在配置文件中指定;\u003ccode\u003erow_format\u003c/code\u003e则在创建数据表时指定:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eCREATE TABLE test2 (column1 INT PRIMARY KEY)\nENGINE=InnoDB ROW_FORMAT=Compressed KEY_BLOCK_SIZE=4;\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"三innodb_file_format--barracuda\"\u003e …\u003c/h2\u003e"
August 16, 2018
DBA必知的MySQL优化原理(推荐)
"\u003cp\u003e推荐阅读: \u003ca href=\"https://www.cnblogs.com/zishengY/p/6892345.html\"\u003ehttps://www.cnblogs.com/zishengY/p/6892345.html\u003c/a\u003e\u003c/p\u003e"
August 16, 2018
MySQL 5.6新特性MRR
"\u003ch2 id=\"一什么是mrr\"\u003e**一、什么是MRR **\u003c/h2\u003e\n\u003cp\u003eMMR全称是Multi-Range Read,是MYSQL5.6优化器的一个新特性,在MariaDB5.5也有这个特性。优化的功能在使用二级索引做范围扫描的过程中减少磁盘随机IO和减少主键索引的访问次数。\u003cstrong\u003e是优化器将随机 IO 转化为顺序 IO 以降低查询过程中 IO 开销的一种手段。\u003c/strong\u003e(参考: \u003ca href=\"https://blog.csdn.net/caomiao2006/article/details/52205177\"\u003ehttps://blog.csdn.net/caomiao2006/article/details/52205177\u003c/a\u003e)\u003c/p\u003e\n\u003ch2 id=\"二mrr和没有mrr的区别\"\u003e**二、MRR和没有MRR的区别 **\u003c/h2\u003e\n\u003cp\u003e给出一个简单的例子,在innodb表执行下面的查询:\u003c/p\u003e\n\u003cp\u003eSELECT non_key_column FROM tbl WHERE key_column=x\u003c/p\u003e\n\u003cp\u003e在没有MRR的情况下,它是这样得到结果的:\u003c/p\u003e\n\u003cp\u003e1. select key_column, pk_column from tb where key_column=x order by key_column —\u0026gt;\n假设这个结果集是t\u003c/p\u003e\n\u003cp\u003e2. for each row in t ;\nselect non_key_column from tb where …\u003c/p\u003e"
August 4, 2018
MySQL中select中的for update 的用法
"\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e注意: FOR UPDATE 只能用在事务区块(BEGIN/COMMIT)中才有效。\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e有时候我们会看到一些select语句后面紧跟一句for update,表示手动加锁的意思,这里我们就介绍一下对for update的理解。相对另一种手动加锁方法lock in share mode 的区别见: \u003ca href=\"https://blog.csdn.net/liangzhonglin/article/details/65438777\"\u003ehttps://blog.csdn.net/liangzhonglin/article/details/65438777\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003efor update:IX锁(意向排它锁),即在符合条件的rows上都加了排它锁,其他session也就无法在这些记录上添加任何的S锁或X锁。如果不存在一致性非锁定读的话,那么其他session是无法读取和修改这些记录的,但是innodb有非锁定读(快照读并不需要加锁),for update之后并不会阻塞其他session的快照读取操作,除了select …lock in share mode和select … for update这种显示加锁的查询操作。\u003c/p\u003e\n\u003cp\u003elock in share mode:是IS锁(意向共享锁),即在符合条件的rows上都加了共享锁,这样的话,其 …\u003c/p\u003e"
August 4, 2018
mysql explain 中key_len的计算方法
"\u003cp\u003e建议先阅读这篇文章: \u003ca href=\"http://hidba.org/?p=404\"\u003ehttp://hidba.org/?p=404\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e下面我们只对其中提到的做一个验证。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e(1).索引字段的附加信息:可以分为变长和定长数据类型讨论,当索引字段为定长数据类型,比如\u003cstrong\u003echar\u003c/strong\u003e,\u003cstrong\u003eint\u003c/strong\u003e,\u003cstrong\u003edatetime\u003c/strong\u003e,需要有是否为空的标记,这个标记需要占用1个字节;对于变长数据类型,比如:varchar,除了是否为空的标记外,还需要有长度信息,需要占用2个字节;\u003c/p\u003e\n\u003cp\u003e(备注:当字段定义为非空的时候,是否为空的标记将不占用字节)\u003c/p\u003e\n\u003cp\u003e(2).同时还需要考虑表所使用的字符集,不同的字符集,gbk编码的为一个字符2个字节,utf8编码的一个字符3个字节, utf8mb4 编码则是4个字节;\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e每种MySQL数据类型的定义参考:\u003c/p\u003e\n\u003cp\u003e下面我们以定长数据类型准,变长数据类型请自行测试。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e一、数据索引类型允许为null的情况:\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e表结构:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eCREATE TABLE `tb` (\n`id` int(10) unsigned NOT NULL AUTO_INCREMENT,\n`sid` smallint(5) DEFAULT NULL,\n`gid` smallint(5) DEFAULT NULL, …\u003c/code\u003e\u003c/pre\u003e"
August 3, 2018
redis list数据类型 不同编码ziplist 和 linkedlist的区别
"\u003cp\u003e\u003ca href=\"https://my.oschina.net/justfairytale/blog/393830\"\u003ehttps://my.oschina.net/justfairytale/blog/393830\u003c/a\u003e\u003c/p\u003e"
August 1, 2018
Redis单线程架构
"\u003ch3 id=\"1-单线程模型\"\u003e1 单线程模型\u003c/h3\u003e\n\u003cp\u003eRedis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行。并且多个客户端发送的命令的执行顺序是不确定的。但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。\u003c/p\u003e\n\u003ch3 id=\"2-单线程模型每秒万级别处理能力的原因\"\u003e2 单线程模型每秒万级别处理能力的原因\u003c/h3\u003e\n\u003cp\u003e(1)纯内存访问。数据存放在内存中,内存的响应时间大约是100纳秒,这是Redis每秒万亿级别访问的重要基础。\u003c/p\u003e\n\u003cp\u003e(2)非阻塞I/O,Redis采用epoll做为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为了时间,不在I/O上浪费过多的时间。\u003c/p\u003e\n\u003cp\u003e(3)单线程避免了线程切换和竞态产生的消耗。\u003c/p\u003e\n\u003cp\u003e(4)Redis采用单线程模型,每条命令执行如果占用大量时间,会造成其他线程阻塞,对于Redis这种高性能服务是致命的,所以Redis是面向高速执行的数据库。\u003c/p\u003e\n\u003cp\u003eredis为什么要设计成单线程: …\u003c/p\u003e"
August 1, 2018
Redis中的锁
"\u003cp\u003e单Redis实例锁: \u003ca href=\"http://www.redis.cn/commands/setnx.html\"\u003ehttp://www.redis.cn/commands/setnx.html\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e分布式锁: \u003ca href=\"http://redis.cn/topics/distlock.html\"\u003ehttp://redis.cn/topics/distlock.html\u003c/a\u003e(提供各种开发语言提供的库)\u003c/p\u003e"
July 30, 2018
MYSQL之ICP、MRR、BKA
"\u003ch1 id=\"index-condition-pushdownicp\"\u003eIndex Condition Pushdown(ICP)\u003c/h1\u003e\n\u003cp\u003eIndex Condition Pushdown (ICP)是mysql使用索引从表中检索行数据的一种优化方式。\u003c/p\u003e\n\u003ch3 id=\"icp原理\"\u003eICP原理\u003c/h3\u003e\n\u003cp\u003e禁用ICP,存储引擎会通过遍历索引定位基表中的行,然后返回给MySQL Server层,再去为这些数据行进行WHERE后的条件的过滤。\u003c/p\u003e\n\u003cp\u003e开启ICP,如果部分WHERE条件能使用索引中的字段,MySQL Server 会把这部分下推到存储引擎层,存储引擎通过索引过滤,把满足的行从表中读取出。ICP能减少引擎层访问基表的次数和MySQL Server 访问存储引擎的次数。\u003c/p\u003e\n\u003cp\u003eICP的目标是减少从基表中全纪录读取操作的数量,从而降低IO操作\u003c/p\u003e\n\u003cp\u003e对于InnoDB表,ICP只适用于辅助索引。\u003c/p\u003e\n\u003ch3 id=\"icp标识\"\u003eICP标识\u003c/h3\u003e\n\u003cp\u003e当使用ICP优化时,执行计划的Extra列显示Using indexcondition提示\u003c/p\u003e\n\u003ch3 id=\"相关参数\"\u003e相关参数\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eoptimizer_switch=\u0026#34;index_condition_pushdown=on”;\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"适用场景\"\u003e适用场景\u003c/h3\u003e\n\u003cp\u003e#辅助索引INDEX (\u003ccode\u003ezipcode\u003c/code\u003e, \u003ccode\u003elastname\u003c/code\u003e, \u003ccode\u003efirstname\u003c/code\u003e).\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eSELECT * …\u003c/code\u003e\u003c/pre\u003e"
July 10, 2018
PHP连接mysql8.0出错“SQLSTATE[HY000] [2054] The server requested authentication method unknown to”的解决办法
"\u003cp\u003e错误信息\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eSQLSTATE[HY000] [2054] The server requested authentication method unknown to…\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e这个错可能是mysql默认使用 \u003ccode\u003ecaching_sha2_password\u003c/code\u003e 作为默认的身份验证插件,而不再是 \u003ccode\u003emysql_native_password\u003c/code\u003e,但是客户端暂时不支持这个插件导致的。 \u003ca href=\"https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html\"\u003e官方文档说明\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn MySQL 8.0, caching_sha2_password is the default authentication plugin rather than mysql_native_password. For information about the implications of this change for server operation and compatibility of the server with clients and connectors, see caching_sha2_password as the Preferred Authentication Plugin.\u003c/p\u003e\n\u003cp\u003e …\u003c/p\u003e\u003c/blockquote\u003e"
July 10, 2018
使用Dockerfile构建Swoole+php7环境
"\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eFROM php:7.2.7-cli\nRUN apt-get update \n \u0026amp;\u0026amp; apt-get install -y libmemcached-dev zlib1g-dev\nRUN pecl install redis-4.0.1 \n \u0026amp;\u0026amp; pecl install swoole-4.0.1 \n \u0026amp;\u0026amp; pecl install memcached-3.0.4 \n \u0026amp;\u0026amp; pecl install xdebug-2.6.0 \n \u0026amp;\u0026amp; docker-php-ext- enable redis swoole memcached xdebug\nCOPY . /usr/src/myapp\nWORKDIR /usr/src/myapp\nCMD [ \u0026#34;php\u0026#34;, \u0026#34;-m\u0026#34; ]\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e构建完环境后,使用方法见: \u003ca href=\"https://blog.haohtml.com/archives/17925\"\u003ehttps://blog.haohtml.com/archives/17925 …\u003c/a\u003e\u003c/p\u003e"
July 6, 2018
MySQL中的查询开销查看方法
"\u003cp\u003eMySQL使用基于 \u003cstrong\u003e成本的优化器\u003c/strong\u003e,它尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最小的一个。在MySQL可以通过查询当前会话的 \u003ccode\u003elast_query_cost\u003c/code\u003e 的值来得到其计算当前查询的成本。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emysql\u003cspan style=\"color:#f92672\"\u003e\u0026gt;\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eselect\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003efrom\u003c/span\u003e t_message \u003cspan style=\"color:#66d9ef\"\u003elimit\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e10\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e...\u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e省略结果集\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emysql\u003cspan style=\"color:#f92672\"\u003e\u0026gt;\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eshow\u003c/span\u003e status \u003cspan style=\"color:#66d9ef\"\u003elike\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;last_query_cost\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e-----------------+-------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e Variable_name \u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e Value \u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e-----------------+-------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e Last_query_cost\u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e6391\u003c/span\u003e.\u003cspan style=\"color:#ae81ff\"\u003e799000\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e+\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e-----------------+-------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e示例中的结果表示优化器认为大概需要做6391个数据页的随机查找才能完成上面的查询。这个结果是根据一些列的统计信息计算得来的,这些统计信息包括: \u003cstrong\u003e每张表或者索引的页面个数\u003c/strong\u003e、 \u003cstrong\u003e索引的基数\u003c/strong\u003e、 \u003cstrong\u003e索引\u003c/strong\u003e 和 \u003cstrong\u003e数据行的长度\u003c/strong\u003e、 \u003cstrong\u003e索引的分布\u003c/strong\u003e 情况等等。\u003c/p\u003e\n\u003cp\u003e有非常多 …\u003c/p\u003e"
July 5, 2018
一个docker-compose微服务脚本,自用
"\u003cp\u003e容器为swoole+php7\u003c/p\u003e\n\u003cp\u003edocker-compose.yml\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eversion: \u0026#39;3.6\u0026#39;\nservices:\n redis:\n image: redis\n web:\n image: cfanbo/swoole4_php7:v1\n depends_on:\n - redis\n links:\n - redis\n volumes:\n - /Users/sxf/sites/msgserve:/usr/src/myapp\n command: \u0026#34;php /usr/src/myapp/src/wx_push_server.php start\u0026#34;\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e对于 wx_push_server.php文件里redis的主机地址应该写成docker-compose配置文件里的容器服务名(redis)\u003c/p\u003e"