Skip to content

upgrade: introduce "permanent" upgrades#91627

Merged
craig[bot] merged 1 commit intocockroachdb:masterfrom
andreimatei:upgrades.permanent
Nov 23, 2022
Merged

upgrade: introduce "permanent" upgrades#91627
craig[bot] merged 1 commit intocockroachdb:masterfrom
andreimatei:upgrades.permanent

Conversation

@andreimatei
Copy link
Copy Markdown
Contributor

@andreimatei andreimatei commented Nov 9, 2022

This patch introduces "permanent" upgrades - a type of upgrade that is
tied to a particular cluster version (just like the existing upgrades)
but that runs regardless of the version at which the cluster was
bootstrapped (in contrast with the existing upgrades that are not run
when they're associated with a cluster version <= the bootstrap
version). These upgrades are called "permanent" because they cannot be
deleted from the codebase at a later point, in contrast with the others
that are deleted once the version they're tied drops below
BinaryMinSupportedVersion).

Existing upgrades are explicitly or implicitly baked into the bootstrap
image of the binary that introduced them. For example, an upgrade that
creates a system table is only run when upgrading an existing,
older-version, cluster to the new version; it does not run for a cluster
bootstrapped by the binary that introduced the upgrade because the
respective system tables are also included in the bootstrap metadata.
For some upcoming upgrades, though, including them in the bootstrap
image is difficult. For example, creating a job record at bootstrap
time is proving to be difficult (the system.jobs table has indexes, so
you want to insert into it through SQL because figuring out the kv's for
a row is tedious, etc). This is where these new permanent upgrades come
in.

These permanent upgrades replace the startupmigrations that don't have
the includedInBootstrap field set. All such startupmigrations have
been copied over as upgrades. None of the current startupmigrations
have includedInBootstrap set (except one but that's dummy one since
the actual migration code has been deleted), so the startupmigrations
package is now deleted. That's a good thing - we had one too many
migrations frameworks.

These permanent upgrades, though, do not have exactly the same semantics
as the startupmigrations they replace. To the extent that there is a
difference, the new semantics are considered more desirable:

  • startupmigrations run when a node that has the code for a particular
    migration startups up for the first time. In other words, the
    startupmigrations were not associated with a cluster version; they were
    associated with a binary version. Migrations can run while old-version
    nodes are still around. This means that one cannot add a
    migration that is a problem for old nodes - e.g. a migration creating a
    job of a type that the old version wouldn't recognize.
  • upgrades are tied to a cluster version - they only run when the
    cluster's active version moves past the upgrade's version. This stays
    the case for the new permanent migrations too, so a v2 node will not
    immediately run the permant migrations introduced since v1 when it joins
    a v1 cluster. Instead, the migrations will run when the cluster version
    is bumped. As such, the migrations can be backwards incompatible.

startupmigrations do arguably have a property that can be desirable:
when there are no backwards compatibility issues, the v2 node can rely
on the effects of the startupmigrations it knows about regardless of the
cluster version. In contrast, with upgrades, not only is a node unable
to simply assume that a particular upgrade has run during startup, but,
more than that, a node is not even able to look at a version gate during
the startup sequence in order to determine whether a particular upgrade
has run or not (because, in clusters that are bootstrapped at v2, the
active cluster version starts as v2 even before the upgrades run). This
is a fact of life for existing upgrades, and now becomes a fact of life
for permanent upgrades too. However, by the time user SQL traffic is
admitted on a node, the node can rely on version gates to correspond to
migrations that have run.

After thinking about it, this possible advantage of startupmigrations
doesn't seem too useful and so it's not reason enough to keep the
startupmigrations machinery around.

Since the relevant startupmigrations have been moved over to upgrades,
and the two libraries use different methods for not running the same
migration twice, a 23.1 node that comes up in a 22.2 cluster will re-run
the several permanent upgrades in question, even though they had already
run as startupmigrations. This is OK since both startupmigrations and
upgrades are idempotent. None of the current permanent upgrades are too
expensive.

Closes #73813

Release note: None
Epic: None

@andreimatei andreimatei requested review from a team, ajwerner and miretskiy November 9, 2022 20:36
@andreimatei andreimatei requested review from a team as code owners November 9, 2022 20:36
@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

@andreimatei andreimatei changed the title upgrade: move most of the upgrade pkg to roachpb.Version upgrade: introduce "permanent" upgrades Nov 9, 2022
@andreimatei andreimatei force-pushed the upgrades.permanent branch 2 times, most recently from 17128f4 to e863abf Compare November 9, 2022 20:45
@andreimatei
Copy link
Copy Markdown
Contributor Author

cc @zachlite

@miretskiy
Copy link
Copy Markdown
Contributor

cc @jayshrivastava

Copy link
Copy Markdown
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to peel the first commit off into a separate PR? This post is just about the first one.

Reviewed 9 of 19 files at r1.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @andreimatei and @miretskiy)


pkg/roachpb/version.go line 73 at r1 (raw file):

		return v.String()
	}
	return redact.Sprintf("%s%s", v.String(), "(fence)").StripMarkers()

why is this not fmt.Sprintf("%v (fence)", v)

Copy link
Copy Markdown

@postamar postamar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this. This feels like a good change, I mostly have quibbles about naming things. I would prefer if this new functionality was exercised somehow to validate that it works as intended before approving it, though.

For this purpose would it be possible to port one or several existing system table data insertions in bootstrap into one of these new migrations? Assigning them the minimum cluster version value should ensure that they always run. For instance I have in mind addSystemTenantEntry which populates system.tenants, which should result in noisy failures if there's bugs.

// Attempt to upgrade cluster version now that the sql server has been
// started. At this point we know that all startupmigrations have successfully
// been run so it is safe to upgrade to the binary's current version.
// started. At this point we know that all startupmigrations and upgrades have
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean startupmigrations and permanent upgrades?


// upgradesManager deals with cluster version upgrades on bootstrap and on
// `set cluster setting version = <v>`.
upgradesManager *upgrademanager.Manager
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uber nit: naming consistency, consider renaming the package to upgradesmanager

return errors.Wrap(err, "ensuring SQL migrations")
}

// Run all the "permanent" upgrades that haven't already run in this cluster,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps I'm reading too much into this: the use of quotes around "permanent" suggests some discomfort with the choice of word to qualify this new type of upgrade. Indeed, all upgrades are permanent in their effects, it's not like you can roll any of them back.

If you're open to naming suggestions, how about describing them as "unconditional upgrades"? Still, that's not quite accurate either, they are also conditional:

  • an upgrade of this new kind might run only if its version <= current active cluster version;
  • an upgrade of the already-existing kind might run only if its version > current active cluster version.

Perhaps consider naming each kind along the lines of "pre-upgrades" and "post-upgrades", respectively? That might be too contrived and unclear, I don't know. Food for thought.

@andreimatei andreimatei requested review from a team as code owners November 16, 2022 00:25
@andreimatei andreimatei requested review from renatolabs and smg260 and removed request for a team November 16, 2022 00:25
@andreimatei
Copy link
Copy Markdown
Contributor Author

Not quite ready for another look, but soon!

andreimatei added a commit to andreimatei/cockroach that referenced this pull request Nov 16, 2022
Upgrades were taking a reference to the job running them. Once upon a
time, this was allegedly used by some upgrade in order to checkpoint its
progress. Nobody uses it currently, and this patch removes it. We can
add it back if we need it again.
This reference was in my way because in cockroachdb#91627 I'm adding a testing mode
where upgrades do not run in jobs.

Release note: None
craig bot pushed a commit that referenced this pull request Nov 16, 2022
91929: startupmigrations: remove useless guard in migration r=andreimatei a=andreimatei

The migration writing the initial value of the cluster version had a conditional about whether it's performing the migration for the system tenant. The migration only runs as the system tenant, courtesy of the clusterWide setting [1]. This patch this replaces the conditional with an assertion.

[1] https://github.com/cockroachdb/cockroach/blob/fd42d376fb5ec42e9d9a30fcdcb210a8a79ef0e2/pkg/startupmigrations/migrations.go#L108

Release note: None
Epic: None

91931: startupmigrations: remove no-op SET CLUSTER SETTING version r=andreimatei a=andreimatei

The migration writing the initial value of the cluster version setting was also performing a `SET CLUSTER SETTING version = v`, where v was the version is had just written in the settings table. This statement was a no-op, because it amounted to an update from v to v [1]. This patch removes the statement.

[1] https://github.com/cockroachdb/cockroach/blob/f87728fee6d16e2a352ac76e7ae9225930032ce6/pkg/upgrade/upgrademanager/manager.go#L167-L171

91998: upgrade: minor cleanups r=andreimatei a=andreimatei

See individual commits.
Extracted from #91627

Release note: None
Epic: None

Co-authored-by: Andrei Matei <andrei@cockroachlabs.com>
@dt
Copy link
Copy Markdown
Contributor

dt commented Nov 18, 2022

First off, my apologies for rolling in late here after there has obviously already been a lot of time and effort invested.

I'm a little concerned about how much this approach complicates the story of a simple linear line of versions and upgrade migrations being how we move along that line.

First, some background, separate from this work: it has been becoming clearer lately, particularly in the context of multi-tenant clusters, that we probably need to change how we bootstrap. Specifically, we probably need to bootstrap a created cluster - in particular a created secondary tenant cluster -- to the minimumBinaryVersion cluster version and associated system schema/state, and then run all the upgrade migrations to get from there to our desired state/version (typically the binary version state).

A big reason this change in approach, versus bootstrapping directly to the final version, seems likely to be forced on us, is tenant creation in a mixed version host cluster: a) we have a hard rule that the tenant cluster version must not exceed the host cluster cluster version b) the initial boostrap state and cluster version is determined today by the the binary that runs it.

Today, that binary bootstraps straight to its final version, regardless of the cluster version, as the bootstrap schema is hardcoded to be the binary version. But that means if you add one new binary to a host cluster -- but do not yet advance the host cluster version -- if that binary happens to handle a CREATE TENANT call, it'd bootstrap that tenant to its binary version, i.e. to a version above the host cluster version, violating our hard rule. This is bad, and we need to fix it ASAP.

So it seems likely that we need to change how we bootstrap, specifically toot hardcode changes to the system schema into the bootstrap schema when we write them, and instead only "flatten" system state changes into to the bootstrap schema when the associated upgrade migration drops below minBinary and is deleted. Thus we'd instead bootstrap to minBinary and run the upgrade migrations after bootstrapping to advance to wherever we want to end up.

Now with that as background, assuming we make those changes, what does that mean for this work? Well, I think it could mean we have a much simpler option for "I want to make sure this gets run in every cluster" than is sketched here: we can just use a standard, run of the mill upgrade migration which we "rebase" any time it falls below minBinary, meaning it is always run, and then any piece of code that wants to e.g. create a job or a schedule or a default user or whatever can simply register itself in this migration.

WDYT?

@andreimatei
Copy link
Copy Markdown
Contributor Author

Now with that as background, assuming we make those changes, what does that mean for this work? Well, I think it could mean we have a much simpler option for "I want to make sure this gets run in every cluster" than is sketched here: we can just use a standard, run of the mill upgrade migration which we "rebase" any time it falls below minBinary, meaning it is always run, and then any piece of code that wants to e.g. create a job or a schedule or a default user or whatever can simply register itself in this migration.

How do you envision this "rebasing" happening? Or, rather, doesn't this patch do what you want? This patch makes it possible to have initialization that's not baked into the bootstrap image (i.e. MakeMetadataSchema()), which I think is what you're talking about. What did you mean by "I'm a little concerned about how much this approach complicates the story of a simple linear line of versions and upgrade migrations being how we move along that line." more concretely?

It seems to me that, whether or not we bootstrap at the minBinary version or at the binaryVersion, this patch remains good - the "permanent upgrades" are the ones that have not been folded into any image, so they always get run. As opposed to the non-permanent upgrades, which only get run for versions above the bootstrap version.

@dt
Copy link
Copy Markdown
Contributor

dt commented Nov 18, 2022

How do you envision this "rebasing" happening?
When minBinary would advance past a never-baked-in migration, we'd simply renumber it to remain above minBinary. But now that I think about it, I'm not even sure we need to do that, if we just bootstrapped to below minBinary, specifically to the earliest version in our list, and then migrated our way up. Anything not permeant below minBinary (which is now a point somewhere in the middle of the list) will have been baked in and removed, so the prefix of the line before minBinary is just the "permeant" ones at that point.

Or, rather, doesn't this patch do what you want?

I guess I'm not sure we need to encode which are permeant or not, or have the distinct "run the permeant ones" phase? If we just had them all as regular ol upgrade migrations, but ensured new clusters initialized to a version below them, then they run just like any upgrade migrations, without needing to make them special at runtime. The only thing special about them is that we don't delete them.

This patch introduces "permanent" upgrades - a type of upgrade that is
tied to a particular cluster version (just like the existing upgrades)
but that runs regardless of the version at which the cluster was
bootstrapped (in contrast with the existing upgrades that are not run
when they're associated with a cluster version <= the bootstrap
version). These upgrades are called "permanent" because they cannot be
deleted from the codebase at a later point, in contrast with the others
that are deleted once the version they're tied drops below
BinaryMinSupportedVersion).

Existing upgrades are explicitly or implicitly baked into the bootstrap
image of the binary that introduced them. For example, an upgrade that
creates a system table is only run when upgrading an existing,
older-version, cluster to the new version; it does not run for a cluster
bootstrapped by the binary that introduced the upgrade because the
respective system tables are also included in the bootstrap metadata.
For some upcoming upgrades, though, including them in the bootstrap
image is difficult. For example, creating a job record at bootstrap
time is proving to be difficult (the system.jobs table has indexes, so
you want to insert into it through SQL because figuring out the kv's for
a row is tedious, etc). This is where these new permanent upgrades come
in.

These permanent upgrades replace the `startupmigrations` that don't have
the `includedInBootstrap` field set. All such startupmigrations have
been copied over as upgrades. None of the current `startupmigrations`
have `includedInBootstrap` set (except one but that's dummy one since
the actual migration code has been deleted), so the startupmigrations
package is now deleted. That's a good thing - we had one too many
migrations frameworks.

These permanent upgrades, though, do not have exactly the same semantics
as the startupmigrations they replace. To the extent that there is a
difference, the new semantics are considered more desirable:
- startupmigrations run when a node that has the code for a particular
  migration startups up for the first time. In other words, the
  startupmigrations were not associated with a cluster version; they were
  associated with a binary version. Migrations can run while old-version
  nodes are still around.  This means that one cannot add a
  migration that is a problem for old nodes - e.g. a migration creating a
  job of a type that the old version wouldn't recognize.
- upgrades are tied to a cluster version - they only run when the
  cluster's active version moves past the upgrade's version. This stays
  the case for the new permanent migrations too, so a v2 node will not
  immediately run the permant migrations introduced since v1 when it joins
  a v1 cluster. Instead, the migrations will run when the cluster version
  is bumped. As such, the migrations can be backwards incompatible.

startupmigrations do arguably have a property that can be desirable:
when there are no backwards compatibility issues, the v2 node can rely
on the effects of the startupmigrations it knows about regardless of the
cluster version. In contrast, with upgrades, not only is a node unable
to simply assume that a particular upgrade has run during startup, but,
more than that, a node is not even able to look at a version gate during
the startup sequence in order to determine whether a particular upgrade
has run or not (because, in clusters that are bootstrapped at v2, the
active cluster version starts as v2 even before the upgrades run). This
is a fact of life for existing upgrades, and now becomes a fact of life
for permanent upgrades too. However, by the time user SQL traffic is
admitted on a node, the node can rely on version gates to correspond to
migrations that have run.

After thinking about it, this possible advantage of startupmigrations
doesn't seem too useful and so it's not reason enough to keep the
startupmigrations machinery around.

Since the relevant startupmigrations have been moved over to upgrades,
and the two libraries use different methods for not running the same
migration twice, a 23.1 node that comes up in a 22.2 cluster will re-run
the several permanent upgrades in question, even though they had already
run as startupmigrations. This is OK since both startupmigrations and
upgrades are idempotent. None of the current permanent upgrades are too
expensive.

Closes cockroachdb#73813

Release note: None
Epic: None
Copy link
Copy Markdown
Contributor Author

@andreimatei andreimatei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TFTRs!

bors r+

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner, @miretskiy, @msbutler, @postamar, @renatolabs, and @smg260)


pkg/upgrade/upgrades/permanent_upgrades.go line 30 at r10 (raw file):

Previously, ajwerner wrote…

wrong errors

done

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Nov 23, 2022

Build succeeded:

@craig craig bot merged commit 1d04cec into cockroachdb:master Nov 23, 2022
andreimatei added a commit to andreimatei/cockroach that referenced this pull request Nov 28, 2022
This patch removes a permanent upgrade that was granting the CREATELOGIN
role option to users that had the CREATEROLE option. This upgrade was
introduced in 20.2, meant to grant the then-new CREATELOGIN option to
users created in 20.1 and prior that had the CREATEROLE option
(CREATELOGIN was being split from CREATEROLE).

This code stayed around as a startupmigration since it was introduced,
even though it didn't make sense for it to stay around after 20.2.
Technically, I think this startup migration should have had the flag
`IncludedInBootstrap=v20.2`, since we don't want it to run for clusters
created at or after 20.2; this migration is not idempotent in the
general sense, since it potentially picks up new, unintended users when
it runs. Since 22.2, this migration would fail to run on anything but an
empty system.role_options table because it would attempt to put NULLs
into a non-nullable column. This was all benign since the
startupmigrations had protection in place, preventing them for running a
2nd time after a completed attempt. So, for upgraded cluster, the
migration only when the first 20.2 node came up, and for new clusters it
would be a no-op since the system.role_options table starts empty.

This migration became problematic in cockroachdb#91627 when I've turned the
startupmigrations into upgrades. These upgrades run once when upgrading
to 23.1; I'm relying on their idempotence.

Fixes cockroachdb#92230
Fixes cockroachdb#92371
Fixes cockroachdb#92569

Release note: None
andreimatei added a commit to andreimatei/cockroach that referenced this pull request Nov 28, 2022
Some of the permanent upgrades (opting into telemetry and initializing
the cluster secret) were not idempotent; this patch makes them be. In
particular, this is important since these upgrades will run on 23.1
cluster that are being upgraded from 22.2 as they've been turned from
startupmigrations to upgrades in cockroachdb#91627. For the telemetry one, there's
no "natural" way to make it idempotent, so I've added a check for the
old startupmigration key.

Release note: None
Epic: None
craig bot pushed a commit that referenced this pull request Nov 28, 2022
92289: catalog,tabledesc: add & adopt Constraint subtypes r=Xiang-Gu a=postamar

These new interfaces help encapsulate the descriptor protobufs for table
constraints:
  - CheckConstraint,
  - ForeignKeyConstraint,
  - UniqueWithoutIndexConstraint,
  - UniqueWithIndexConstraint.

These are the leaves of the Constraint type tree, and Constraint is the
interface at the root of it. The changes in this commit mimic what was
done for Column & Index, which respectively wrap descpb.ColumnDescriptor
and descpb.IndexDescriptor.

These new constraint interfaces are adopted liberally throughout the
code base, but not completely: many references to descpb-protobufs still
need to be replaced.

This commit also removes the somewhat confusing concept of "active"
versus "inactive" constraint. Not only was it confusing to me, evidently
it was also confusing to other contributors considering how several mild
bugs and inconsistencies made their way into the code. This commit
replaces this concept with that of an "enforced" constraint:
  - A constraint is enforced if it applies to data written to the table,
    regardless of whether it has been validated on the data already in
    the table prior to the constraint coming into existence.

The implementation is somewhat awkward for constraints in that the same
constraint descriptor can be featured twice inside
a descpb.TableDescriptor, in its active constraint slice (such as
Checks, etc.) and also in the Mutations slice. In these cases the
interface wraps the non-mutation constraint descriptor protobuf, with no
observed changes to the database's behavior.

This commit required alterations to the table descriptor's
post-deserialization changes. The change which assigns constraint IDs
to table descriptors which don't have themhad some subtle bugs which went
unnoticed until this commit forced a heavier reliance on these fields.
This commit also adds a new change which ensures that a check
constraint's ColumnIDs slice is populated based on the columns
referenced in its expression, replacing ancient code which predates the
concept of post-deserialization changes and which would compute this
lazily.

As a more general observation: it appears that the handling of adding
and dropping constraints following other schema changes was mildly
inconsistent and this commit tries to improve this. For instance, it was
possible to drop a column which had been set as NOT NULL in the same
transaction, but not do the same for any other kind of constraint. Also
it was possible to reuse the name of a dropping constraint, despite this
constraint still being enforced. The new behavior is more strict, yet
this should be barely noticeable by the user in most practical cases:
it's rare that one wants to add a constraint referencing a column and
also drop that column in the same transaction, for instance.

Fixes #91918.

Release note: None

92597: upgrades: remove upgrade granting CREATELOGIN role opt r=andreimatei a=andreimatei

This patch removes a permanent upgrade that was granting the CREATELOGIN role option to users that had the CREATEROLE option. This upgrade was introduced in 20.2, meant to grant the then-new CREATELOGIN option to users created in 20.1 and prior that had the CREATEROLE option (CREATELOGIN was being split from CREATEROLE).

This code stayed around as a startupmigration since it was introduced, even though it didn't make sense for it to stay around after 20.2. Technically, I think this startup migration should have had the flag `IncludedInBootstrap=v20.2`, since we don't want it to run for clusters created at or after 20.2; this migration is not idempotent in the general sense, since it potentially picks up new, unintended users when it runs. Since 22.2, this migration would fail to run on anything but an empty system.role_options table because it would attempt to put NULLs into a non-nullable column. This was all benign since the startupmigrations had protection in place, preventing them for running a 2nd time after a completed attempt. So, for upgraded cluster, the migration only when the first 20.2 node came up, and for new clusters it would be a no-op since the system.role_options table starts empty.

This migration became problematic in #91627 when I've turned the startupmigrations into upgrades. These upgrades run once when upgrading to 23.1; I'm relying on their idempotence.

Fixes #92230
Fixes #92371
Fixes #92569

Release note: None
Epic: None

Co-authored-by: Marius Posta <marius@cockroachlabs.com>
Co-authored-by: Andrei Matei <andrei@cockroachlabs.com>
andreimatei added a commit to andreimatei/cockroach that referenced this pull request Dec 2, 2022
Some of the permanent upgrades (opting into telemetry and initializing
the cluster secret) were not idempotent; this patch makes them be. In
particular, this is important since these upgrades will run on 23.1
cluster that are being upgraded from 22.2 as they've been turned from
startupmigrations to upgrades in cockroachdb#91627. For the telemetry one, there's
no "natural" way to make it idempotent, so I've added a check for the
old startupmigration key.

Release note: None
Epic: None
craig bot pushed a commit that referenced this pull request Dec 2, 2022
90842: sql: add tsvector and tsquery types to SQL r=jordanlewis a=jordanlewis

Updates #41288.

Broken off from #83736

This PR adds the tsvector and tsquery types and pgwire encodings to sql, and makes them available for use using the string::tsvector and string::tsquery casts. It also implements the in-memory evaluation of `@@` (the tsquery match operator) by delegating to the tsearch.eval package.

Release note (sql change): implement in memory handling for the tsquery and tsvector Postgres datatypes, which provide text search capabilities. See https://www.postgresql.org/docs/current/datatype-textsearch.html for more details.

Epic: None

92611: upgrades: make a couple of permanent upgrades idempotent r=andreimatei a=andreimatei

Some of the permanent upgrades (opting into telemetry and initializing the cluster secret) were not idempotent; this patch makes them be. In particular, this is important since these upgrades will run on 23.1 cluster that are being upgraded from 22.2 as they've been turned from startupmigrations to upgrades in #91627. For the telemetry one, there's no "natural" way to make it idempotent, so I've added a check for the old startupmigration key.

Release note: None
Epic: None

92620: upgrademanager: clarify job running code r=andreimatei a=andreimatei

This patch makes the code clearer around running upgrade in jobs. Before this patch, the upgrade manager was looking for existing jobs corresponding to upgrades and, if it found them, it called jobsRegistry.Run() on them - just like it did for newly-created jobs. The behavior of Run() for jobs that are not already claimed by the registry is a bit under-specified. I believe it ended up printing an error [1] and then correctly waiting for the job to finish.

This patch no longer calls Run() for existing jobs; instead, it calls WaitForJobs(), which is more suggestive.

[1] https://github.com/cockroachdb/cockroach/blob/b2a6b80920324bd6b31cba9a6f622961979de600/pkg/jobs/adopt.go#L255

Release note: None
Epic: None

Co-authored-by: Jordan Lewis <jordanthelewis@gmail.com>
Co-authored-by: Andrei Matei <andrei@cockroachlabs.com>
andreimatei added a commit to andreimatei/cockroach that referenced this pull request Dec 8, 2022
This patch makes the "primordial" permanent upgrades not run in clusters
being upgraded from 22.2 or lower.

Startup migrations were recently replaced with "permanent upgrades", in cockroachdb#91627.
The permanent new upgrades were running on node startup regardless of
whether it was a "new cluster" or an existing one - i.e. regardless of
whether the previous startupmigrations had also run, on the argument
that startupmigrations and upgrades are supposed to be idempotent
anyway. But, alas, there's idempotency and then there's idempotency:
startupmigrations/upgrades are supposed to be OK with running multiple
times at the same BinaryVersion in a "new cluster", but not necessarily
across BinaryVersions and in a cluster that has been in use. There are
different things that can go wrong when one of these migrations runs
multiple times in these general conditions, because the migration
might makes implicit assumptions about the schema and data of the
cluster it's running in:
1. A migration might assume that all the data in a system table was
   created before a CRDB version changed some semantics. For example,
   the migration deleted in cockroachdb#92597 was assuming that `CREATEROLE` role
   option had a certain meaning for all the users who have it and was doing
   a backfill across all these users. Running this migration again at an
   arbitrary later point would affect unintended new users.
2. A migration assumes the schema of system tables it operates on. As
   this schema (which is part of the bootstrap image for new cluster)
   changes with new versions, the code of the upgrade changes also. This
   means that the upgrade is no longer suitable for running against
   clusters that don't have the upgraded schema - i.e. clusters that have
   not yet been upgraded to the latest schema. This is a real problem
   because we're adding a column to system.users, and the addRootUser
   upgrade can no longer run against 22.2 clusters.

This patch guards all upgrades on checking that the old corresponding
startupmigration has not run, thus enabling the mentioned system schema
change in 23.1.

Release note: None
Epic: None
andreimatei added a commit to andreimatei/cockroach that referenced this pull request Dec 8, 2022
This patch makes the "primordial" permanent upgrades not run in clusters
being upgraded from 22.2 or lower.

Startup migrations were recently replaced with "permanent upgrades", in cockroachdb#91627.
The permanent new upgrades were running on node startup regardless of
whether it was a "new cluster" or an existing one - i.e. regardless of
whether the previous startupmigrations had also run, on the argument
that startupmigrations and upgrades are supposed to be idempotent
anyway. But, alas, there's idempotency and then there's idempotency:
startupmigrations/upgrades are supposed to be OK with running multiple
times at the same BinaryVersion in a "new cluster", but not necessarily
across BinaryVersions and in a cluster that has been in use. There are
different things that can go wrong when one of these migrations runs
multiple times in these general conditions, because the migration
might makes implicit assumptions about the schema and data of the
cluster it's running in:
1. A migration might assume that all the data in a system table was
   created before a CRDB version changed some semantics. For example,
   the migration deleted in cockroachdb#92597 was assuming that `CREATEROLE` role
   option had a certain meaning for all the users who have it and was doing
   a backfill across all these users. Running this migration again at an
   arbitrary later point would affect unintended new users.
2. A migration assumes the schema of system tables it operates on. As
   this schema (which is part of the bootstrap image for new cluster)
   changes with new versions, the code of the upgrade changes also. This
   means that the upgrade is no longer suitable for running against
   clusters that don't have the upgraded schema - i.e. clusters that have
   not yet been upgraded to the latest schema. This is a real problem
   because we're adding a column to system.users, and the addRootUser
   upgrade can no longer run against 22.2 clusters.

This patch guards all upgrades on checking that the old corresponding
startupmigration has not run, thus enabling the mentioned system schema
change in 23.1.

Release note: None
Epic: None
craig bot pushed a commit that referenced this pull request Dec 8, 2022
92363: sql,streamingest: introduce ALTER TENANT ... PAUSE/RESUME REPLICATION r=lidorcarmel a=adityamaru

This change introduces:
`ALTER TENANT <name> RESUME REPLICATION`
`ALTER TENANT <name> PAUSE REPLICATION`

These statements can be used to pause and resume the replication job if the tenant is being replicated into.

Fixes: #91246

Release note: None

93071: upgrade: don't blindly run permanent migrations r=andreimatei a=andreimatei

This patch makes the "primordial" permanent upgrades not run in clusters
being upgraded from 22.2 or lower.

Startup migrations were recently replaced with "permanent upgrades", in #91627.
The permanent new upgrades were running on node startup regardless of
whether it was a "new cluster" or an existing one - i.e. regardless of
whether the previous startupmigrations had also run, on the argument
that startupmigrations and upgrades are supposed to be idempotent
anyway. But, alas, there's idempotency and then there's idempotency:
startupmigrations/upgrades are supposed to be OK with running multiple
times at the same BinaryVersion in a "new cluster", but not necessarily
across BinaryVersions and in a cluster that has been in use. There are
different things that can go wrong when one of these migrations runs
multiple times in these general conditions, because the migration
might makes implicit assumptions about the schema and data of the
cluster it's running in:
1. A migration might assume that all the data in a system table was
   created before a CRDB version changed some semantics. For example,
   the migration deleted in #92597 was assuming that `CREATEROLE` role
   option had a certain meaning for all the users who have it and was doing
   a backfill across all these users. Running this migration again at an
   arbitrary later point would affect unintended new users.
2. A migration assumes the schema of system tables it operates on. As
   this schema (which is part of the bootstrap image for new cluster)
   changes with new versions, the code of the upgrade changes also. This
   means that the upgrade is no longer suitable for running against
   clusters that don't have the upgraded schema - i.e. clusters that have
   not yet been upgraded to the latest schema. This is a real problem
   because we're adding a column to system.users, and the addRootUser
   upgrade can no longer run against 22.2 clusters.

This patch guards all upgrades on checking that the old corresponding
startupmigration has not run, thus enabling the mentioned system schema
change in 23.1.

Release note: None
Epic: None

Co-authored-by: adityamaru <adityamaru@gmail.com>
Co-authored-by: Andrei Matei <andrei@cockroachlabs.com>
ajwerner added a commit to ajwerner/cockroach that referenced this pull request Jan 17, 2023
This is no longer referenced since cockroachdb#91627.

Epic: none

Release note: None
craig bot pushed a commit that referenced this pull request Jan 17, 2023
94239: loqrecovery: use captured meta range content for LOQ plans r=erikgrinaker a=aliher1911

Note: only last commit belongs to this PR. Will update description once #93157 lands.

Previously loss of quorum recovery planner was using local replica info collected from all nodes to find source of truth for replicas that lost quorum.
With online approach local info snapshots don't have atomicity. This could cause planner to fail if available replicas are caught in different states on different nodes.
This commit adds alternative planning approach when range metadata is available. Instead of fixing individual replicas that can't make progress it finds ranges that can't make progress from metadata using descriptors and updates their replicas to recover from loss of quorum.
This commit also adds replica collection stage as a part of make-plan command itself. To invoke collection from a cluster instead of using files one needs to provide --host and other standard cluster connection related flags (--cert-dir, --insecure etc.) as appropriate.

Example command output for a local cluster with 3 out of 5 nodes surrvivng looks like:
```
~/tmp ❯❯❯ cockroach debug recover make-plan --insecure --host 127.0.0.1:26257 >recover-plan.json
Nodes scanned:           3
Total replicas analyzed: 228
Ranges without quorum:   15
Discarded live replicas: 0

Proposed changes:
  range r4:/System/tsd updating replica (n2,s2):3 to (n2,s2):15. Discarding available replicas: [], discarding dead replicas: [(n5,s5):4,(n4,s4):2].
  range r80:/Table/106/1 updating replica (n1,s1):1 to (n1,s1):14. Discarding available replicas: [], discarding dead replicas: [(n5,s5):3,(n4,s4):2].
  range r87:/Table/106/1/"paris"/"\xcc\xcc\xcc\xcc\xcc\xcc@\x00\x80\x00\x00\x00\x00\x00\x00(" updating replica (n1,s1):1 to (n1,s1):14. Discarding available replicas: [], discarding dead replicas: [(n5,s5):3,(n4,s4):2].
  range r88:/Table/106/1/"seattle"/"ffffffH\x00\x80\x00\x00\x00\x00\x00\x00\x14" updating replica (n3,s3):3 to (n3,s3):15. Discarding available replicas: [], discarding dead replicas: [(n5,s5):4,(n4,s4):2].
  range r105:/Table/106/1/"washington dc"/"L\xcc\xcc\xcc\xcc\xccL\x00\x80\x00\x00\x00\x00\x00\x00\x0f" updating replica (n3,s3):3 to (n3,s3):14. Discarding available replicas: [], discarding dead replicas: [(n5,s5):1,(n4,s4):2].
  range r98:/Table/107/1/"boston"/"333333D\x00\x80\x00\x00\x00\x00\x00\x00\x03" updating replica (n2,s2):3 to (n2,s2):15. Discarding available replicas: [], discarding dead replicas: [(n5,s5):4,(n4,s4):2].
  range r95:/Table/107/1/"seattle"/"ffffffH\x00\x80\x00\x00\x00\x00\x00\x00\x06" updating replica (n3,s3):2 to (n3,s3):15. Discarding available replicas: [], discarding dead replicas: [(n4,s4):4,(n5,s5):3].
  range r125:/Table/107/1/"washington dc"/"DDDDDDD\x00\x80\x00\x00\x00\x00\x00\x00\x04" updating replica (n3,s3):2 to (n3,s3):14. Discarding available replicas: [], discarding dead replicas: [(n4,s4):1,(n5,s5):3].
  range r115:/Table/108/1/"boston"/"8Q\xeb\x85\x1e\xb8B\x00\x80\x00\x00\x00\x00\x00\x00n" updating replica (n2,s2):3 to (n2,s2):15. Discarding available replicas: [], discarding dead replicas: [(n5,s5):4,(n4,s4):2].
  range r104:/Table/108/1/"new york"/"\x1c(\xf5\u008f\\I\x00\x80\x00\x00\x00\x00\x00\x007" updating replica (n2,s2):2 to (n2,s2):15. Discarding available replicas: [], discarding dead replicas: [(n5,s5):4,(n4,s4):3].
  range r102:/Table/108/1/"seattle"/"p\xa3\xd7\n=pD\x00\x80\x00\x00\x00\x00\x00\x00\xdc" updating replica (n3,s3):2 to (n3,s3):15. Discarding available replicas: [], discarding dead replicas: [(n4,s4):4,(n5,s5):3].
  range r126:/Table/108/1/"washington dc"/"Tz\xe1G\xae\x14L\x00\x80\x00\x00\x00\x00\x00\x00\xa5" updating replica (n3,s3):2 to (n3,s3):14. Discarding available replicas: [], discarding dead replicas: [(n4,s4):1,(n5,s5):3].
  range r86:/Table/108/3 updating replica (n1,s1):1 to (n1,s1):14. Discarding available replicas: [], discarding dead replicas: [(n4,s4):3,(n5,s5):2].
  range r59:/Table/109/1 updating replica (n2,s2):3 to (n2,s2):15. Discarding available replicas: [], discarding dead replicas: [(n5,s5):4,(n4,s4):2].
  range r65:/Table/111/1 updating replica (n3,s3):3 to (n3,s3):15. Discarding available replicas: [], discarding dead replicas: [(n5,s5):4,(n4,s4):2].

Discovered dead nodes would be marked as decommissioned:
  n4, n5


Proceed with plan creation [y/N] y
Plan created.
To stage recovery application in half-online mode invoke:

'cockroach debug recover apply-plan  --host=127.0.0.1:26257 --insecure=true <plan file>'

Alternatively distribute plan to below nodes and invoke 'debug recover apply-plan --store=<store-dir> <plan file>' on:
- node n2, store(s) s2
- node n1, store(s) s1
- node n3, store(s) s3
```

Release note: None

Fixes: #93038
Fixes: #93046

94948: changefeedccl: give notice when metrics_label set without child_metrics r=samiskin a=samiskin

Resolves #75682

Surfaces a notice of
```
server.child_metrics.enabled is set to false, metrics will only be published to the '<scope>' label when it is set to true"
```
When child_metrics setting isn't enabled during changefeed creation

Release note (enterprise change): Changefeeds created/altered with a metrics_label set while server.child_metrics.enabled is false will now provide the user a notice upon creation.

95009: tree: fix panic when encoding tuple r=rafiss a=rafiss

fixes #95008

This adds a bounds check to avoid a panic.

Release note (bug fix): Fixed a crash that could happen when formatting a tuple with an unknown type.

95294: sql: make pg_description aware of builtin function descriptions r=rafiss,msirek a=knz

Epic: CRDB-23454
Fixes #95292.
Needed for #88061. 

First commit from #95289.

This also extends the completion rules to properly handle
functions in multiple namespaces.

Release note (bug fix): `pg_catalog.pg_description` and `pg_catalog.obj_description()` are now able to retrieve the descriptive help for built-in functions.

95356: server: remove unused migrationExecutor r=ajwerner a=ajwerner

This is no longer referenced since #91627.

Epic: none

Release note: None

Co-authored-by: Oleg Afanasyev <oleg@cockroachlabs.com>
Co-authored-by: Shiranka Miskin <shiranka.miskin@gmail.com>
Co-authored-by: Rafi Shamim <rafi@cockroachlabs.com>
Co-authored-by: Raphael 'kena' Poss <knz@thaumogen.net>
Co-authored-by: Andrew Werner <awerner32@gmail.com>
rafiss added a commit to rafiss/cockroach that referenced this pull request Nov 26, 2024
This partially reverts commit 129d62a.

It also fixes the roachtest that was added in the previous commit.

In PR cockroachdb#119142, the permanent upgrades were flattened so that they
all have a version of 0.0-x. That means that the last element of
the permanentUpgrades slice has a version of 0.0-4. Clusters that were
bootstrapped with a version from v23.1.0 or later will have rows in
system.migrations for versions 0.0-x, since that is the version where
the permanent upgrades framework was introduced (in PR cockroachdb#91627).
However, clusters that are were bootstrapped from a version
earlier than v23.1 will not yet have these rows in system.migrations for
versions 0.0-x, and those migrations will only be present under the
legacy startupmigrations key.

Release note (bug fix): Fixed a bug that could cause the password for
the root user to be deleted while upgrading to v24.1. This bug only
affects clusters that were initially created with a version of v22.2
or earlier.

The same bug could also cause the `defaultdb` and `postgres` databases
to be recreated during the upgrade to v24.1 if they had been previously
deleted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

migration/startupmigrations: remove all startupmigrations

6 participants