Cwww3's Blog

Record what you think

0%

进程

状态

创建 就绪 运行 阻塞 阻塞挂起 就绪挂起 结束

程序阻塞时,会将程序所占用的物理内存,swap到硬盘上,此时进程进入了挂起状态

程序sleep也会导致挂起

阅读全文 »

物理内存,大小有限,多个程序使用,不易分配。

引入虚拟地址,程序的视角认为整个内存只有它在使用。程序间相互隔离,互不影响。

CPU 中的内存管理单元(MMU),负责将虚拟地址转化为实际的物理地址。

阅读全文 »

Sql源码浅析

Connect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
func Open(driverName, dataSourceName string) (*DB, error) {
// 查找已注册的驱动 由_ "github.com/go-sql-driver/mysql"提供
// 驱动是真正和数据库打交道的
driversMu.RLock()
driveri, ok := drivers[driverName]
driversMu.RUnlock()
if !ok {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
}



if driverCtx, ok := driveri.(driver.DriverContext); ok {
// 获取连接器
connector, err := driverCtx.OpenConnector(dataSourceName)
if err != nil {
return nil, err
}
return OpenDB(connector), nil
}

return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
}


// OpenDB may just validate its arguments without creating a connection
// to the database. To verify that the data source name is valid, call
// Ping.
func OpenDB(c driver.Connector) *DB {
// 初始化数据,为后续维护连接池做准备
ctx, cancel := context.WithCancel(context.Background())
db := &DB{
connector: c,
openerCh: make(chan struct{}, connectionRequestQueueSize),
lastPut: make(map[*driverConn]string),
connRequests: make(map[uint64]chan connRequest),
stop: cancel,
}

go db.connectionOpener(ctx)

return db
}

// Runs in a separate goroutine, opens new connections when requested.
func (db *DB) connectionOpener(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
case <-db.openerCh:
// 收到创建新的连接的请求
db.openNewConnection(ctx)
}
}
}
阅读全文 »

GORM 源码浅析

连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// gorm 连接数据库
func Open(dialector Dialector, opts ...Option) (db *DB, err error) {
// 全局配置
config := &Config{}

...

// 加载配置
for _, opt := range opts {
if opt != nil {
if applyErr := opt.Apply(config); applyErr != nil {
return nil, applyErr
}
defer func(opt Option) {
if errr := opt.AfterInitialize(db); errr != nil {
err = errr
}
}(opt)
}
}

// 时间精度配置 默认毫秒
if d, ok := dialector.(interface{ Apply(*Config) error }); ok {
if err = d.Apply(config); err != nil {
return
}
}


// 注册query/create..等操作执行时所需要调用的函数
// gorm:query -> gorm:preload -> gorm:after_query
// 对不同版本的数据库做相应的约束配置
// 调用sql.Open()初始化连接池
db.callbacks = initializeCallbacks(db)
if config.Dialector != nil {
err = config.Dialector.Initialize(db)
}

...

// clone=1
db = &DB{Config: config, clone: 1}

// 在执行sql前后,相关的信息都会存在其中
db.Statement = &Statement{
DB: db,
ConnPool: db.ConnPool,
Context: context.Background(),
Clauses: map[string]clause.Clause{},
}

// 连接时,自动会进行ping操作
if err == nil && !config.DisableAutomaticPing {
if pinger, ok := db.ConnPool.(interface{ Ping() error }); ok {
err = pinger.Ping()
}
}

if err != nil {
config.Logger.Error(context.Background(), "failed to initialize database, got error %v", err)
}

return
}

阅读全文 »

查看是否开启binlog

1
show variables like 'log_bin';

查看binlog

1
show binary logs
阅读全文 »