From 9157a4b45c43a20b58ad21ccaf97889453d396f2 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Fri, 24 Mar 2017 17:32:50 +0000 Subject: [PATCH] sql: introduce system.settings table this will be used to store and manage cluster-wide, runtime changable settings. this introduces the new table via a migration -- later work will use it to provide settings accessors for calling code. --- pkg/cli/cli_test.go | 1 + pkg/keys/constants.go | 1 + pkg/migrations/migrations.go | 21 ++++++++++ pkg/sql/pgwire/pgwire_test.go | 2 +- pkg/sql/sqlbase/system.go | 41 +++++++++++++++++++ pkg/sql/system_table_test.go | 1 + .../testdata/logic_test/information_schema | 13 ++++++ pkg/sql/testdata/logic_test/system | 40 ++++++++++++++++-- 8 files changed, 116 insertions(+), 4 deletions(-) diff --git a/pkg/cli/cli_test.go b/pkg/cli/cli_test.go index b83e8d3ed0f2..50790f4187dd 100644 --- a/pkg/cli/cli_test.go +++ b/pkg/cli/cli_test.go @@ -1667,6 +1667,7 @@ writing ` + os.DevNull + ` debug/schema/system/lease debug/schema/system/namespace debug/schema/system/rangelog + debug/schema/system/settings debug/schema/system/ui debug/schema/system/users debug/schema/system/zones diff --git a/pkg/keys/constants.go b/pkg/keys/constants.go index c1dbece46b7e..117e71b0ee23 100644 --- a/pkg/keys/constants.go +++ b/pkg/keys/constants.go @@ -286,6 +286,7 @@ const ( DescriptorTableID = 3 UsersTableID = 4 ZonesTableID = 5 + SettingsTableID = 6 // Reserved IDs for other system tables. If you're adding a new system table, // it probably belongs here. diff --git a/pkg/migrations/migrations.go b/pkg/migrations/migrations.go index 36920e308027..f1562a6c3b39 100644 --- a/pkg/migrations/migrations.go +++ b/pkg/migrations/migrations.go @@ -54,6 +54,12 @@ var backwardCompatibleMigrations = []migrationDescriptor{ newDescriptors: 1, newRanges: 1, }, + { + name: "create system.settings table", + workFn: createSettingsTable, + newDescriptors: 1, + newRanges: 0, // it lives in gossip range. + }, } // migrationDescriptor describes a single migration hook that's used to modify @@ -334,3 +340,18 @@ func createJobsTable(ctx context.Context, r runner) error { return txn.Run(ctx, b) }) } + +func createSettingsTable(ctx context.Context, r runner) error { + // We install the table at the KV layer so that we can choose a known ID in + // the reserved ID space. (The SQL layer doesn't allow this.) + return r.db.Txn(ctx, func(ctx context.Context, txn *client.Txn) error { + b := txn.NewBatch() + desc := sqlbase.SettingsTable + b.CPut(sqlbase.MakeNameMetadataKey(desc.GetParentID(), desc.GetName()), desc.GetID(), nil) + b.CPut(sqlbase.MakeDescMetadataKey(desc.GetID()), sqlbase.WrapDescriptor(&desc), nil) + if err := txn.SetSystemConfigTrigger(); err != nil { + return err + } + return txn.Run(ctx, b) + }) +} diff --git a/pkg/sql/pgwire/pgwire_test.go b/pkg/sql/pgwire/pgwire_test.go index a8800d9f532a..3745b9998cf7 100644 --- a/pkg/sql/pgwire/pgwire_test.go +++ b/pkg/sql/pgwire/pgwire_test.go @@ -579,7 +579,7 @@ func TestPGPreparedQuery(t *testing.T) { baseTest.Results("users", "primary", true, 1, "username", "ASC", false, false), }, "SHOW TABLES FROM system": { - baseTest.Results("descriptor").Others(8), + baseTest.Results("descriptor").Others(9), }, "SHOW CONSTRAINTS FROM system.users": { baseTest.Results("users", "primary", "PRIMARY KEY", "username", gosql.NullString{}), diff --git a/pkg/sql/sqlbase/system.go b/pkg/sql/sqlbase/system.go index ececa99cbbe4..4ba27329e81a 100644 --- a/pkg/sql/sqlbase/system.go +++ b/pkg/sql/sqlbase/system.go @@ -60,6 +60,15 @@ CREATE TABLE system.zones ( id INT PRIMARY KEY, config BYTES );` + + SettingsTableSchema = ` +CREATE TABLE system.settings ( + name STRING NOT NULL PRIMARY KEY, + value STRING NOT NULL, + lastUpdated TIMESTAMP NOT NULL DEFAULT now(), + valueType STRING, + FAMILY (name, value, lastUpdated, valueType) +);` ) // These system tables are not part of the system config. @@ -153,6 +162,10 @@ var SystemAllowedPrivileges = map[ID]privilege.Lists{ keys.DescriptorTableID: {privilege.ReadData}, keys.UsersTableID: {privilege.ReadWriteData}, keys.ZonesTableID: {privilege.ReadWriteData}, + // We eventually want to migrate the table to appear read-only to force the + // the use of a validating, logging accessor, so we'll go ahead and tolerate + // read-only privs to make that migration possible later. + keys.SettingsTableID: {privilege.ReadWriteData, privilege.ReadData}, keys.LeaseTableID: {privilege.ReadWriteData, {privilege.ALL}}, keys.EventLogTableID: {privilege.ReadWriteData, {privilege.ALL}}, keys.RangeEventTableID: {privilege.ReadWriteData, {privilege.ALL}}, @@ -296,6 +309,34 @@ var ( FormatVersion: InterleavedFormatVersion, NextMutationID: 1, } + // SettingsTable is the descriptor for the jobs table. + SettingsTable = TableDescriptor{ + Name: "settings", + ID: keys.SettingsTableID, + ParentID: 1, + Version: 1, + Columns: []ColumnDescriptor{ + {Name: "name", ID: 1, Type: colTypeString}, + {Name: "value", ID: 2, Type: colTypeString}, + {Name: "lastUpdated", ID: 3, Type: colTypeTimestamp, DefaultExpr: &nowString}, + {Name: "valueType", ID: 4, Type: colTypeString, Nullable: true}, + }, + NextColumnID: 5, + Families: []ColumnFamilyDescriptor{ + { + Name: "fam_0_name_value_lastUpdated_valueType", + ID: 0, + ColumnNames: []string{"name", "value", "lastUpdated", "valueType"}, + ColumnIDs: []ColumnID{1, 2, 3, 4}, + }, + }, + NextFamilyID: 1, + PrimaryIndex: pk("name"), + NextIndexID: 2, + Privileges: NewPrivilegeDescriptor(security.RootUser, SystemDesiredPrivileges(keys.SettingsTableID)), + FormatVersion: InterleavedFormatVersion, + NextMutationID: 1, + } ) // These system TableDescriptor literals should match the descriptor that diff --git a/pkg/sql/system_table_test.go b/pkg/sql/system_table_test.go index 6b5a0ed975f2..00d8fda108f3 100644 --- a/pkg/sql/system_table_test.go +++ b/pkg/sql/system_table_test.go @@ -118,6 +118,7 @@ func TestSystemTableLiterals(t *testing.T) { {keys.RangeEventTableID, sqlbase.RangeEventTableSchema, sqlbase.RangeEventTable}, {keys.UITableID, sqlbase.UITableSchema, sqlbase.UITable}, {keys.JobsTableID, sqlbase.JobsTableSchema, sqlbase.JobsTable}, + {keys.SettingsTableID, sqlbase.SettingsTableSchema, sqlbase.SettingsTable}, } { gen, err := sql.CreateTestTableDescriptor( context.TODO(), diff --git a/pkg/sql/testdata/logic_test/information_schema b/pkg/sql/testdata/logic_test/information_schema index 207e4727f4ea..bcc1bfc55c25 100644 --- a/pkg/sql/testdata/logic_test/information_schema +++ b/pkg/sql/testdata/logic_test/information_schema @@ -257,6 +257,7 @@ jobs lease namespace rangelog +settings ui users zones @@ -274,6 +275,7 @@ tables table_privileges table_constraints statistics +settings schemata schema_privileges schema_changes @@ -357,6 +359,7 @@ def system jobs BASE TABLE 1 def system lease BASE TABLE 1 def system namespace BASE TABLE 1 def system rangelog BASE TABLE 1 +def system settings BASE TABLE 1 def system ui BASE TABLE 1 def system users BASE TABLE 1 def system zones BASE TABLE 1 @@ -482,6 +485,7 @@ def system primary system jobs def system primary system lease PRIMARY KEY def system primary system namespace PRIMARY KEY def system primary system rangelog PRIMARY KEY +def system primary system settings PRIMARY KEY def system primary system ui PRIMARY KEY def system primary system users PRIMARY KEY def system primary system zones PRIMARY KEY @@ -553,6 +557,10 @@ def system rangelog eventType 4 def system rangelog otherRangeID 5 def system rangelog info 6 def system rangelog uniqueID 7 +def system settings name 1 +def system settings value 2 +def system settings lastUpdated 3 +def system settings valueType 4 def system ui key 1 def system ui value 2 def system ui lastUpdated 3 @@ -756,6 +764,11 @@ NULL root def system rangelog GRANT NULL root def system rangelog INSERT NULL NULL NULL root def system rangelog SELECT NULL NULL NULL root def system rangelog UPDATE NULL NULL +NULL root def system settings DELETE NULL NULL +NULL root def system settings GRANT NULL NULL +NULL root def system settings INSERT NULL NULL +NULL root def system settings SELECT NULL NULL +NULL root def system settings UPDATE NULL NULL NULL root def system ui DELETE NULL NULL NULL root def system ui GRANT NULL NULL NULL root def system ui INSERT NULL NULL diff --git a/pkg/sql/testdata/logic_test/system b/pkg/sql/testdata/logic_test/system index c10f1a898c74..d3da5c63d087 100644 --- a/pkg/sql/testdata/logic_test/system +++ b/pkg/sql/testdata/logic_test/system @@ -18,6 +18,7 @@ jobs lease namespace rangelog +settings ui users zones @@ -33,9 +34,10 @@ EXPLAIN (DEBUG) SELECT * FROM system.namespace 5 /namespace/primary/1/'lease'/id 11 ROW 6 /namespace/primary/1/'namespace'/id 2 ROW 7 /namespace/primary/1/'rangelog'/id 13 ROW -8 /namespace/primary/1/'ui'/id 14 ROW -9 /namespace/primary/1/'users'/id 4 ROW -10 /namespace/primary/1/'zones'/id 5 ROW +8 /namespace/primary/1/'settings'/id 6 ROW +9 /namespace/primary/1/'ui'/id 14 ROW +10 /namespace/primary/1/'users'/id 4 ROW +11 /namespace/primary/1/'zones'/id 5 ROW query ITI rowsort SELECT * FROM system.namespace @@ -48,6 +50,7 @@ SELECT * FROM system.namespace 1 lease 11 1 namespace 2 1 rangelog 13 +1 settings 6 1 ui 14 1 users 4 1 zones 5 @@ -60,6 +63,7 @@ SELECT id FROM system.descriptor 3 4 5 +6 11 12 13 @@ -143,6 +147,14 @@ status STRING false NULL {jobs_status_created_idx} created TIMESTAMP false now() {jobs_status_created_idx} payload BYTES false NULL {} +query TTBTT +SHOW COLUMNS FROM system.settings +---- +name STRING false NULL {primary} +value STRING false NULL {} +lastUpdated TIMESTAMP false now() {} +valueType STRING true NULL {} + # Verify default privileges on system tables. query TTT SHOW GRANTS ON DATABASE system @@ -225,6 +237,15 @@ jobs root INSERT jobs root SELECT jobs root UPDATE +query TTT +SHOW GRANTS ON system.settings +---- +settings root DELETE +settings root GRANT +settings root INSERT +settings root SELECT +settings root UPDATE + statement error user root does not have DROP privilege on database system ALTER DATABASE system RENAME TO not_system @@ -292,3 +313,16 @@ GRANT ALL ON system.lease TO root statement ok GRANT ALL ON system.lease TO testuser + +query TTTT +select * from system.settings +---- + +statement ok +INSERT INTO system.settings (name, value) VALUES ('somesetting', 'somevalue') + +query TT +select name, value from system.settings +---- +somesetting somevalue +