使用docker-compose 快速创建一个mysql 数据库容器

//创建一个独立的容器目录

mkdir docker-db
cd docker-db

前提、创建 docker Compose 配置文件
#vi docker-compose.yml 文件,内容如下

version: '3.6'

services: 

    db:
        image: mysql:5.7
        restart: always
        environment:
            MYSQL_ROOT_PASSWORD: 123456
            MYSQL_DATABASE: wordpress
            MYSQL_USER: root
            MYSQL_PASSWORD: 123456
            MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
        ports:
            - "33061:3306"

上面的 ports 这一块,是指宿主机端口号:容器端口号。在使用的时候,直接访问本机的 33061 端口即可。端口号前也可以指定一个固定的IP 地址。
Compose file version 3 reference:https://docs.docker.com/compose/compose-file/

一、创建并启动容器

$docker-composer up

在 docker-composr.yml 所在的目录里,执行上面的命令,此时会自动从远程服务器拉取容器所需的信息。这时窗口一直处于运行状态,我们通过添加
-d
参数,来实现后台服务运行。

二、停止关闭容器

$ docker-compose stop

关闭后,容器文件仍然在磁盘上存在,重新执行 docker-compose start 即可启动。

三、删除容器

docker-compose rm

上面的命令可以将已经停止运行的容器进行删除,也可以将停止和删除用一条命令代替

docker-compose down

更多命令请执行 docker-compose -h 查看。

MySQL InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

InnoDB是一个支持行锁的存储引擎,锁的类型有:共享锁(S)、排他锁(X)、意向共享(IS)、意向排他(IX)。为了提供更好的并发,InnoDB提供了非锁定读:不需要等待访问行上的锁释放,读取行的一个快照。该方法是通过InnoDB的一个特性:MVCC来实现的。

InnoDB有三种行锁的算法:

单个行记录上的锁。

2,Gap Lock:间隙锁,锁定一个范围,但不包括记录本身。GAP锁的目的,是为了防止同一事务的两次当前读,出现幻读的情况。

3,Next-Key Lock:1+2,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。

锁的是索引,并不是记录。
记录锁(Record Lock): 单个索引行记录上的锁
间隙锁(Gap Lock):一般是针对非唯一索引而言的.
后码锁(Next-Key Lock):记录锁和间隙锁的结合,对于InnoDB中,更新非唯一索引对应的记录,会加上Next-Key Lock。如果更新记录为空,就不能加记录锁,只能加间隙锁。

Next-Key Lock是行锁与间隙锁的组合,这样,当InnoDB扫描索引记录的时候,会首先对选中的索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。如果一个间隙被事务T1加了锁,其它事务是不能在这个间隙插入记录的。

https://blog.csdn.net/zhanghongzheng3213/article/details/51721903

http://blog.sina.com.cn/s/blog_a1e9c7910102vnrj.html

https://www.cnblogs.com/zhoujinyi/p/3435982.html

http://hedengcheng.com/?p=771

聚簇索引概念(Myisam与Innodb索引的区别)转推荐

myisam的主索引和次索引都指向物理行,下面来进行讲解

innodb的主键下存储该行的数据,此索引指向对主键的引用

myisam的索引存储图如下,可以看出,无论是id还是cat_id,下面都存储有存储物理地址的值。通过主键索引或者次索引来查询数据的时候,都是先查找到数据地址,然后再到物理位置上去寻找数据

innodb的索引存储图如下,我们会发现,主键索引下面直接存储有数据,而次索引下,存储的是主键的id。通过主键查找数据的时候,就会很快查找到数据,但是通过次索引查找数据的时候,需要先查找到对应的主键id,然后才能查找到对应的数据。 Continue reading

Go中slice作为参数传递的一些“坑”

https://juejin.im/post/5a9f543a6fb9a028cb2d2b91

看明白了上面的文章,下面的例子基本也就明白了

 

package main

import "fmt"

func main() {
	a := []int{1,2,3}
	abc(a)
	fmt.Println(a)
}
func abc(a []int) {
	a[0] = 2 //修改后还是原来的a
	a = append(a, 4) // 此a非原a,使用append导致了重新分配内存地址(存储空间不足,系统自动分配一块新的足够大的内存地址,此时a的物理内存地址已经发行了变化,并将原来a的值copy一份到新的内存地址,所以这里修改的只是新内存地址的值,原来内存地址的值并没有改变),试着删除这行运行一次再看结果
	fmt.Println(a)
	
	a[0] = 7 // 新a,因为上面执行了append
	fmt.Println(a)
	
	fmt.Printf("\n===\n")
}

解释:

golang中string rune byte 三者的关系

在Golang中 string 底层是用byte字节数组存储的,并且是不可以修改的。

例如

s:="Go编程"
fmt.Println(len(s)) //输出结果应该是8因为中文字符是用3个字节存的(2+3*2=8)。
fmt.Printf("%d", len(string(rune('编')))) //经测试一个汉字确实占用3个字节,所以结果是3

如果想要获得字符个数的话,需要先转换为rune切片再使用内置的len函数

fmt.Println(len([]rune(s))) // 结果就是4了。

所以用string存储unicode的话,如果有中文,按下标是访问不到的,因为你只能得到一个byte。 要想访问中文的话,还是要用rune切片,这样就能按下表访问。

总结:
rune 能操作任何字符
byte 不支持中文的操作

示例:https://blog.haohtml.com/archives/14903

解决mac下brew link python3出错brew Error: Permission denied @ dir_s_mkdir - /usr/local/Frameworks

mac上默认的python版本为2.7.10版本,需要升级到python3 版本,通过brew升级

$brew install python3

提示错误

$ brew install python3 Warning: python3 3.6.3 is already installed, it's just not linked. You can use `brew link python3` to link this version. $ brew link python3 Linking /usr/local/Cellar/python3/3.6.3... Error: Permission denied @ dir_s_mkdir

发现/usr/local/下没有路径/usr/local/Frameworks
需要新建该路径,并修改权限

解决:

$ sudo mkdir /usr/local/Frameworks
$ sudo chown $(whoami):admin /usr/local/Frameworks

成功:

$ brew link python3
Linking /usr/local/Cellar/python3/3.6.3... 1 symlinks created

参考:
https://github.com/Homebrew/homebrew-core/issues/19286