-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
metadata_tables.go
98 lines (84 loc) · 3.36 KB
/
metadata_tables.go
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
Copyright 2017 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mysqlctl
import (
"bytes"
"vitess.io/vitess/go/sqltypes"
"vitess.io/vitess/go/vt/log"
)
// Note that definitions of local_metadata and shard_metadata should be the same
// as in testing which is defined in config/init_db.sql.
const sqlCreateLocalMetadataTable = `CREATE TABLE IF NOT EXISTS _vt.local_metadata (
name VARCHAR(255) NOT NULL,
value VARCHAR(255) NOT NULL,
PRIMARY KEY (name)
) ENGINE=InnoDB`
const sqlCreateShardMetadataTable = `CREATE TABLE IF NOT EXISTS _vt.shard_metadata (
name VARCHAR(255) NOT NULL,
value MEDIUMBLOB NOT NULL,
PRIMARY KEY (name)
) ENGINE=InnoDB`
// populateMetadataTables creates and fills the _vt.local_metadata table and
// creates _vt.shard_metadata table. _vt.local_metadata table is
// a per-tablet table that is never replicated. This allows queries
// against local_metadata to return different values on different tablets,
// which is used for communicating between Vitess and MySQL-level tools like
// Orchestrator (http://github.com/github/orchestrator).
// _vt.shard_metadata is a replicated table with per-shard information, but it's
// created here to make it easier to create it on databases that were running
// old version of Vitess, or databases that are getting converted to run under
// Vitess.
func populateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string) error {
log.Infof("Populating _vt.local_metadata table...")
// Get a non-pooled DBA connection.
conn, err := mysqld.GetDbaConnection()
if err != nil {
return err
}
defer conn.Close()
// Disable replication on this session. We close the connection after using
// it, so there's no need to re-enable replication when we're done.
if _, err := conn.ExecuteFetch("SET @@session.sql_log_bin = 0", 0, false); err != nil {
return err
}
// Create the database and table if necessary.
if _, err := conn.ExecuteFetch("CREATE DATABASE IF NOT EXISTS _vt", 0, false); err != nil {
return err
}
if _, err := conn.ExecuteFetch(sqlCreateLocalMetadataTable, 0, false); err != nil {
return err
}
if _, err := conn.ExecuteFetch(sqlCreateShardMetadataTable, 0, false); err != nil {
return err
}
// Populate local_metadata from the passed list of values.
if _, err := conn.ExecuteFetch("BEGIN", 0, false); err != nil {
return err
}
for name, val := range localMetadata {
nameValue := sqltypes.NewVarChar(name)
valValue := sqltypes.NewVarChar(val)
queryBuf := bytes.Buffer{}
queryBuf.WriteString("INSERT INTO _vt.local_metadata (name,value) VALUES (")
nameValue.EncodeSQL(&queryBuf)
queryBuf.WriteByte(',')
valValue.EncodeSQL(&queryBuf)
queryBuf.WriteString(") ON DUPLICATE KEY UPDATE value = ")
valValue.EncodeSQL(&queryBuf)
if _, err := conn.ExecuteFetch(queryBuf.String(), 0, false); err != nil {
return err
}
}
_, err = conn.ExecuteFetch("COMMIT", 0, false)
return err
}