Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Schema Tracking case-sensitive #14904

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 0 additions & 139 deletions go/mysql/endtoend/schema_change_test.go

This file was deleted.

27 changes: 0 additions & 27 deletions go/mysql/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,6 @@ const (
// ShowRowsRead is the query used to find the number of rows read.
ShowRowsRead = "show status like 'Innodb_rows_read'"

// DetectSchemaChange query detects if there is any schema change from previous copy.
DetectSchemaChange = `
SELECT DISTINCT table_name
FROM (
SELECT table_name, column_name, ordinal_position, character_set_name, collation_name, data_type, column_key
FROM information_schema.columns
WHERE table_schema = database()

UNION ALL

SELECT table_name, column_name, ordinal_position, character_set_name, collation_name, data_type, column_key
FROM %s.schemacopy
WHERE table_schema = database()
) _inner
GROUP BY table_name, column_name, ordinal_position, character_set_name, collation_name, data_type, column_key
HAVING COUNT(*) = 1
`

// ClearSchemaCopy query clears the schemacopy table.
ClearSchemaCopy = `delete from %s.schemacopy where table_schema = database()`

// InsertIntoSchemaCopy query copies over the schema information from information_schema.columns table.
InsertIntoSchemaCopy = `insert %s.schemacopy
select table_schema, table_name, column_name, ordinal_position, character_set_name, collation_name, data_type, column_key
from information_schema.columns
where table_schema = database()`

// GetColumnNamesQueryPatternForTable is used for mocking queries in unit tests
GetColumnNamesQueryPatternForTable = `SELECT COLUMN_NAME.*TABLE_NAME.*%s.*`
)
Expand Down
2 changes: 1 addition & 1 deletion go/test/endtoend/vreplication/sidecardb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var ddls1, ddls2 []string

func init() {
sidecarDBTables = []string{"copy_state", "dt_participant", "dt_state", "heartbeat", "post_copy_action", "redo_state",
"redo_statement", "reparent_journal", "resharding_journal", "schema_migrations", "schema_version", "schemacopy", "tables",
"redo_statement", "reparent_journal", "resharding_journal", "schema_migrations", "schema_version", "tables",
"vdiff", "vdiff_log", "vdiff_table", "views", "vreplication", "vreplication_log"}
numSidecarDBTables = len(sidecarDBTables)
ddls1 = []string{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,7 @@ func TestNewUnshardedTable(t *testing.T) {
require.NoError(t, err)
defer conn.Close()

vtgateVersion, err := cluster.GetMajorVersion("vtgate")
require.NoError(t, err)
expected := `[[VARCHAR("dual")] [VARCHAR("main")]]`
if vtgateVersion >= 17 {
expected = `[[VARCHAR("main")]]`
}
expected := `[[VARCHAR("main")]]`

// ensuring our initial table "main" is in the schema
utils.AssertMatchesWithTimeout(t, conn,
Expand All @@ -138,10 +133,7 @@ func TestNewUnshardedTable(t *testing.T) {
// create a new table which is not part of the VSchema
utils.Exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`)

expected = `[[VARCHAR("dual")] [VARCHAR("main")] [VARCHAR("new_table_tracked")]]`
if vtgateVersion >= 17 {
expected = `[[VARCHAR("main")] [VARCHAR("new_table_tracked")]]`
}
expected = `[[VARCHAR("main")] [VARCHAR("new_table_tracked")]]`

// waiting for the vttablet's schema_reload interval to kick in
utils.AssertMatchesWithTimeout(t, conn,
Expand Down Expand Up @@ -176,14 +168,63 @@ func TestNewUnshardedTable(t *testing.T) {
utils.Exec(t, conn, `drop table new_table_tracked`)

// waiting for the vttablet's schema_reload interval to kick in
expected = `[[VARCHAR("dual")] [VARCHAR("main")]]`
if vtgateVersion >= 17 {
expected = `[[VARCHAR("main")]]`
}
expected = `[[VARCHAR("main")]]`
utils.AssertMatchesWithTimeout(t, conn,
"SHOW VSCHEMA TABLES",
expected,
100*time.Millisecond,
30*time.Second,
"new_table_tracked not in vschema tables")
}

// TestCaseSensitiveSchemaTracking tests that schema tracking is case-sensitive.
// This test only works on Linux (and not on Windows and Mac) since it has a case-sensitive file system, so it allows
// creating two tables having the same name differing only in casing, but other operating systems don't.
// More information at https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html#:~:text=Table%20names%20are%20stored%20in,lowercase%20on%20storage%20and%20lookup.
func TestCaseSensitiveSchemaTracking(t *testing.T) {
utils.SkipIfBinaryIsBelowVersion(t, 19, "vttablet")
GuptaManan100 marked this conversation as resolved.
Show resolved Hide resolved
defer cluster.PanicHandler(t)

// create a sql connection
ctx := context.Background()
conn, err := mysql.Connect(ctx, &vtParams)
require.NoError(t, err)
defer conn.Close()

// ensuring our initial table "main" is in the schema
utils.AssertMatchesWithTimeout(t, conn,
"SHOW VSCHEMA TABLES",
`[[VARCHAR("main")]]`,
100*time.Millisecond,
30*time.Second,
"initial tables not found in vschema")

// Now we create two tables with the same name differing only in casing t1 and T1.
// For both of them we'll have different schema's and verify that we can read the data after schema tracking kicks in.
utils.Exec(t, conn, `create table t1(id bigint, primary key(id)) Engine=InnoDB`)
utils.Exec(t, conn, `create table T1(col bigint, col2 bigint, primary key(col)) Engine=InnoDB`)

// Wait for schema tracking to be caught up
utils.AssertMatchesWithTimeout(t, conn,
"SHOW VSCHEMA TABLES",
`[[VARCHAR("T1")] [VARCHAR("main")] [VARCHAR("t1")]]`,
100*time.Millisecond,
30*time.Second,
"schema tracking didn't track both the tables")

// Run DMLs
utils.Exec(t, conn, `insert into t1(id) values(0),(1)`)
utils.Exec(t, conn, `insert into T1(col, col2) values(0,0),(1,1)`)

// Verify the tables are queryable
utils.AssertMatchesWithTimeout(t, conn,
`select * from t1`, `[[INT64(0)] [INT64(1)]]`,
100*time.Millisecond,
30*time.Second,
"could not query expected rows in t1 through vtgate")
utils.AssertMatchesWithTimeout(t, conn,
`select * from T1`, `[[INT64(0) INT64(0)] [INT64(1) INT64(1)]]`,
100*time.Millisecond,
30*time.Second,
"could not query expected rows in T1 through vtgate")
}
4 changes: 2 additions & 2 deletions go/vt/sidecardb/schema/schemaengine/tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ limitations under the License.

CREATE TABLE IF NOT EXISTS tables
(
TABLE_SCHEMA varchar(64) NOT NULL,
TABLE_NAME varchar(64) NOT NULL,
TABLE_SCHEMA varchar(64) CHARACTER SET `utf8mb4` COLLATE `utf8mb4_0900_bin` NOT NULL,
TABLE_NAME varchar(64) CHARACTER SET `utf8mb4` COLLATE `utf8mb4_0900_bin` NOT NULL,
GuptaManan100 marked this conversation as resolved.
Show resolved Hide resolved
CREATE_STATEMENT longtext,
CREATE_TIME BIGINT,
PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME)
Expand Down
4 changes: 2 additions & 2 deletions go/vt/sidecardb/schema/schemaengine/views.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ limitations under the License.

CREATE TABLE IF NOT EXISTS views
(
TABLE_SCHEMA varchar(64) NOT NULL,
TABLE_NAME varchar(64) NOT NULL,
TABLE_SCHEMA varchar(64) CHARACTER SET `utf8mb4` COLLATE `utf8mb4_0900_bin` NOT NULL,
TABLE_NAME varchar(64) CHARACTER SET `utf8mb4` COLLATE `utf8mb4_0900_bin` NOT NULL,
CREATE_STATEMENT longtext,
VIEW_DEFINITION longtext NOT NULL,
PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME)
Expand Down
28 changes: 0 additions & 28 deletions go/vt/sidecardb/schema/schematracker/schemacopy.sql

This file was deleted.

Loading
Loading