dolt icon indicating copy to clipboard operation
dolt copied to clipboard

Panic accessing `information_schema` when mixing old and new storage formats

Open timsehn opened this issue 2 years ago • 7 comments

2022-06-07T09:54:31-07:00 WARN [conn 9] error running query {connectTime=2022-06-07T09:54:31-07:00, connectionDb=getting_started, error=panic in ExchangeIterPartitionRows: unknown message id M, query=SELECT column_name as column_name FROM information_schema.statistics WHERE table_schema = 'getting_started' AND table_name = 'employees_teams' AND index_name = 'PRIMARY' ORDER BY seq_in_index ASC}
2022-06-07T09:54:31-07:00 INFO [conn %!d(<nil>)] kill query: pid 128 {}
2022-06-07T09:54:31-07:00 INFO [conn 9] ConnectionClosed {}
2022-06-07T09:54:31-07:00 ERROR [conn %!d(<nil>)] mysql_server caught panic:
unknown message id M 
/Users/timsehn/liquidata/git/dolt/go/store/prolly/message/message.go:49 (0x16fb229)
	com/dolthub/dolt/go/store/prolly/message.GetKeysAndValues: panic(fmt.Sprintf("unknown message id %s", id))
/Users/timsehn/liquidata/git/dolt/go/store/prolly/tree/node.go:72 (0x1df8630)
	com/dolthub/dolt/go/store/prolly/tree.NodeFromBytes: keys, values, count := message.GetKeysAndValues(msg)
/Users/timsehn/liquidata/git/dolt/go/store/prolly/shim.go:31 (0x1df8594)
	com/dolthub/dolt/go/store/prolly.NodeFromValue: return tree.NodeFromBytes(v.(types.TupleRowStorage))
/Users/timsehn/liquidata/git/dolt/go/store/prolly/shim.go:43 (0x1df88dc)
	com/dolthub/dolt/go/store/prolly.MapFromValue: root := NodeFromValue(v)
/Users/timsehn/liquidata/git/dolt/go/libraries/doltcore/doltdb/durable/table.go:800 (0x1e1af77)
	com/dolthub/dolt/go/libraries/doltcore/doltdb/durable.doltDevTable.GetTableRows: m := prolly.MapFromValue(types.TupleRowStorage(rowbytes), sch, t.vrw)
/Users/timsehn/liquidata/git/dolt/go/libraries/doltcore/doltdb/table.go:268 (0x224bbad)
	com/dolthub/dolt/go/libraries/doltcore/doltdb.(*Table).GetRowData: return t.table.GetTableRows(ctx)
/Users/timsehn/liquidata/git/dolt/go/libraries/doltcore/sqle/index/dolt_index.go:115 (0x224bb94)
	com/dolthub/dolt/go/libraries/doltcore/sqle/index.getPrimaryKeyIndex: tableRows, err := t.GetRowData(ctx)
/Users/timsehn/liquidata/git/dolt/go/libraries/doltcore/sqle/index/dolt_index.go:96 (0x224b81b)
	com/dolthub/dolt/go/libraries/doltcore/sqle/index.DoltIndexesFromTable: idx, err := getPrimaryKeyIndex(ctx, db, tbl, t, sch)
/Users/timsehn/liquidata/git/dolt/go/libraries/doltcore/sqle/tables.go:189 (0x22fee64)
	com/dolthub/dolt/go/libraries/doltcore/sqle.(*DoltTable).GetIndexes: return index.DoltIndexesFromTable(ctx, t.db.Name(), t.tableName, tbl)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/index_analyzer.go:49 (0x21a76c3)
	com/dolthub/go-mysql-server/sql/analyzer.newIndexAnalyzerForNode.func1: idxes, err := it.GetIndexes(ctx)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/index_analyzer.go:76 (0x21a74db)
	com/dolthub/go-mysql-server/sql/analyzer.newIndexAnalyzerForNode.func2: err := indexesForTable(n.Name(), n)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/walk.go:49 (0x1eb0930)
	com/dolthub/go-mysql-server/sql/transform.inspector.Visit: if f(node) {
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/walk.go:35 (0x1eb081a)
	com/dolthub/go-mysql-server/sql/transform.Walk: if v = v.Visit(node); v == nil {
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/walk.go:60 (0x21a7351)
	com/dolthub/go-mysql-server/sql/transform.Inspect: Walk(inspector(f), node)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/index_analyzer.go:60 (0x21a72ea)
	com/dolthub/go-mysql-server/sql/analyzer.newIndexAnalyzerForNode: transform.Inspect(n, func(n sql.Node) bool {
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/assign_info_schema.go:84 (0x219bcf6)
	com/dolthub/go-mysql-server/sql/analyzer.getIndexesForTable: ia, err := newIndexAnalyzerForNode(ctx, node)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/assign_info_schema.go:39 (0x219b667)
	com/dolthub/go-mysql-server/sql/analyzer.loadInfoSchema.func1: tableIndexes, err := getIndexesForTable(ctx, a, x.Child)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/node.go:337 (0x1eb0511)
	com/dolthub/go-mysql-server/sql/transform.Node: node, sameN, err := f(node)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/assign_info_schema.go:27 (0x219b552)
	com/dolthub/go-mysql-server/sql/analyzer.loadInfoSchema: return transform.Node(n, func(n sql.Node) (sql.Node, transform.TreeIdentity, error) {
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/batch.go:120 (0x219de3c)
	com/dolthub/go-mysql-server/sql/analyzer.(*Batch).evalOnce: next, same, err = rule.Apply(ctx, a, prev, scope, sel)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/batch.go:66 (0x219d82c)
	com/dolthub/go-mysql-server/sql/analyzer.(*Batch).EvalWithSelector: cur, _, err := b.evalOnce(ctx, a, n, scope, sel)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/batch.go:56 (0x2190cb0)
	com/dolthub/go-mysql-server/sql/analyzer.(*Batch).Eval: return b.EvalWithSelector(ctx, a, n, scope, sel)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/analyzer.go:521 (0x21909b0)
	com/dolthub/go-mysql-server/sql/analyzer.(*Analyzer).analyzeWithSelector: n, same, err = batch.Eval(ctx, a, n, scope, ruleSelector)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/analyzer.go:371 (0x21efb1a)
	com/dolthub/go-mysql-server/sql/analyzer.(*Analyzer).Analyze: n, _, err := a.analyzeWithSelector(ctx, n, scope, SelectAllBatches, DefaultRuleSelector)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/resolve_tables.go:165 (0x21efaee)
	com/dolthub/go-mysql-server/sql/analyzer.getAllColumnsWithDefaultValue.func1: analyzed, err := a.Analyze(ctx, st, nil)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/core.go:918 (0x15f0330)
	com/dolthub/go-mysql-server/sql.DBTableIter: cont, err := cb(tbl)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/resolve_tables.go:162 (0x21ef8cb)
	com/dolthub/go-mysql-server/sql/analyzer.getAllColumnsWithDefaultValue: err := sql.DBTableIter(ctx, db, func(t sql.Table) (cont bool, err error) {
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/resolve_tables.go:146 (0x21ef664)
	com/dolthub/go-mysql-server/sql/analyzer.handleInfoSchemaColumnsTable: allColsWithDefaults, err := getAllColumnsWithDefaultValue(ctx, a)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/resolve_tables.go:132 (0x21ef078)
	com/dolthub/go-mysql-server/sql/analyzer.resolveTable: return handleInfoSchemaColumnsTable(ctx, resolvedTableNode, a)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/resolve_tables.go:71 (0x21eea88)
	com/dolthub/go-mysql-server/sql/analyzer.resolveTables.func1: r, err := resolveTable(ctx, p, a)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/node.go:188 (0x1eaf535)
	com/dolthub/go-mysql-server/sql/transform.nodeWithCtxHelper: return f(c)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/node.go:199 (0x1eaf71e)
	com/dolthub/go-mysql-server/sql/transform.nodeWithCtxHelper: child, same, err := nodeWithCtxHelper(cc, s, f)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/node.go:199 (0x1eaf71e)
	com/dolthub/go-mysql-server/sql/transform.nodeWithCtxHelper: child, same, err := nodeWithCtxHelper(cc, s, f)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/transform/node.go:176 (0x1eaf3b0)
	com/dolthub/go-mysql-server/sql/transform.NodeWithCtx: return nodeWithCtxHelper(Context{n, nil, -1, sql.Schema{}}, s, f)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/resolve_tables.go:47 (0x21ee854)
	com/dolthub/go-mysql-server/sql/analyzer.resolveTables: return transform.NodeWithCtx(n, nil, func(c transform.Context) (sql.Node, transform.TreeIdentity, error) {
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/batch.go:120 (0x219de3c)
	com/dolthub/go-mysql-server/sql/analyzer.(*Batch).evalOnce: next, same, err = rule.Apply(ctx, a, prev, scope, sel)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/batch.go:66 (0x219d82c)
	com/dolthub/go-mysql-server/sql/analyzer.(*Batch).EvalWithSelector: cur, _, err := b.evalOnce(ctx, a, n, scope, sel)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/batch.go:56 (0x2190cb0)
	com/dolthub/go-mysql-server/sql/analyzer.(*Batch).Eval: return b.EvalWithSelector(ctx, a, n, scope, sel)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/analyzer.go:521 (0x21909b0)
	com/dolthub/go-mysql-server/sql/analyzer.(*Analyzer).analyzeWithSelector: n, same, err = batch.Eval(ctx, a, n, scope, ruleSelector)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/sql/analyzer/analyzer.go:371 (0x22115f4)
	com/dolthub/go-mysql-server/sql/analyzer.(*Analyzer).Analyze: n, _, err := a.analyzeWithSelector(ctx, n, scope, SelectAllBatches, DefaultRuleSelector)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/engine.go:324 (0x22115c9)
	com/dolthub/go-mysql-server.(*Engine).analyzeQuery: analyzed, err = e.Analyzer.Analyze(ctx, parsed, nil)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/engine.go:193 (0x2210a6e)
	com/dolthub/go-mysql-server.(*Engine).QueryNodeWithBindings: analyzed, err = e.analyzeQuery(ctx, query, parsed, bindings)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/server/handler.go:343 (0x228b456)
	com/dolthub/go-mysql-server/server.(*Handler).doQuery: schema, rowIter, err := h.e.QueryNodeWithBindings(ctx, query, parsed, sqlBindings)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/server/handler.go:607 (0x228e067)
	com/dolthub/go-mysql-server/server.(*Handler).errorWrappedDoQuery: remainder, err := h.doQuery(c, query, mode, bindings, callback)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/server/handler.go:160 (0x22894a8)
	com/dolthub/go-mysql-server/server.(*Handler).ComMultiQuery: return h.errorWrappedDoQuery(c, query, MultiStmtModeOn, nil, callback)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/go/mysql/conn.go:1286 (0x1529cf1)
	com/dolthub/vitess/go/mysql.(*Conn).execQuery: remainder, err = handler.ComMultiQuery(c, query, resultsCB)
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/go/mysql/conn.go:930 (0x15266f8)
	com/dolthub/vitess/go/mysql.(*Conn).handleNextCommand: for query, err = c.execQuery(query, handler, multiStatements); err == nil && query != ""; {
/Users/timsehn/go/pkg/mod/github.com/dolthub/[email protected]/go/mysql/server.go:479 (0x153fd2a)
	com/dolthub/vitess/go/mysql.(*Listener).handle: err := c.handleNextCommand(l.handler)
/usr/local/go/src/runtime/asm_amd64.s:1571 (0x106a100)
	goexit: BYTE	$0x90	// NOP

timsehn avatar Jun 07 '22 23:06 timsehn

I'm not sure how I triggered it. But the steps I took are in issue #3558

timsehn avatar Jun 07 '22 23:06 timsehn

This happened as I was composing a query against employees_teams.

After the panic, it disconnects from the database and I have to reconnect so this is customer facing.

timsehn avatar Jun 07 '22 23:06 timsehn

I think this may have to do with the table having multiple primary keys.

timsehn avatar Jun 07 '22 23:06 timsehn

Even simpler repro:

mysql> select * from information_schema.statistics;
ERROR 1105 (HY000): panic in ExchangeIterPartitionRows: unknown message id M

timsehn avatar Jun 07 '22 23:06 timsehn

Does not happen unless in sql-server mode:

getting_started $ dolt sql -q "select * from information_schema.statistics"
+---------------+-----------------+-----------------+------------+-----------------+-------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+------------+
| table_catalog | table_schema    | table_name      | non_unique | index_schema    | index_name  | seq_in_index | column_name | collation | cardinality | sub_part | packed | nullable | index_type | comment | index_comment | is_visible | expression |
+---------------+-----------------+-----------------+------------+-----------------+-------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+------------+
| def           | getting_started | employees       | 0          | getting_started | PRIMARY     | 1            | id          | A         | 5           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
| def           | getting_started | employees       | 0          | getting_started | id          | 1            | id          | A         | 5           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
| def           | getting_started | employees_teams | 0          | getting_started | PRIMARY     | 1            | team_id     | A         | 5           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
| def           | getting_started | employees_teams | 0          | getting_started | PRIMARY     | 2            | employee_id | A         | 5           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
| def           | getting_started | employees_teams | 1          | getting_started | employee_id | 1            | employee_id | A         | 5           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
| def           | getting_started | employees_teams | 1          | getting_started | team_id     | 1            | team_id     | A         | 5           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
| def           | getting_started | teams           | 0          | getting_started | PRIMARY     | 1            | id          | A         | 2           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
| def           | getting_started | teams           | 0          | getting_started | id          | 1            | id          | A         | 2           | NULL     | NULL   |          | BTREE      |         |               | YES        | NULL       |
+---------------+-----------------+-----------------+------------+-----------------+-------------+--------------+-------------+-----------+-------------+----------+--------+----------+------------+---------+---------------+------------+------------+

timsehn avatar Jun 07 '22 23:06 timsehn

Easy repro:

  1. Start a dolt sql-server
  2. Connect with a mysql client
  3. Run:
dolt $ mysql --host 127.0.0.1 --port 3306 -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.9-Vitess 

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database easy_panic;
Query OK, 1 row affected (0.01 sec)

mysql> use easy_panic;
Database changed
mysql> select * from information_schema.statistics;
ERROR 1105 (HY000): panic in ExchangeIterPartitionRows: unknown message id M

timsehn avatar Jun 07 '22 23:06 timsehn

This had to do with me having new format databases in the same directory as old format databases. information_schema needs to access every database the server can see. When it hit the new format databases it panicked.

Deleting the new format databases resolved the issue.

timsehn avatar Jun 07 '22 23:06 timsehn

Closing in favor of #4077

timsehn avatar Aug 31 '22 16:08 timsehn