-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Summary: Enable `FOR UPDATE` and `FOR NO KEY UPDATE` row locking statements with the caveat that `FOR NO KEY UPDATE` behaves like `FOR UPDATE` (see follow-up issue #2922). Also, fix conflict detection such that `FOR SHARE` locks do not conflict with each other. Implement the fix as follows: 1. Pass down `FOR UPDATE` and `FOR NO KEY UPDATE` row locks through Protobufs. 1. Pass them through `PgsqlReadRequestPB.row_mark_type`. (Also, change the field from `repeated` to `optional`.) 1. Pass them through `KeyValueWriteBatchPB.row_mark_type`. (Also, change the field from `repeated` to `optional`.) 1. Add a row lock parameter to `docdb::GetStrongIntentTypeSet`, and permeate row lock information throughout the affected areas (fix issue #2842). Remove the isolation level hack in `tablet::Tablet::PrepareTransactionWriteBatch` in favor of using row lock information (fix issue #2496). 1. Create a new value type `kRowLock` to be placed in the value of intents for row locking. Handle this value type in `docdb::(anonymous namespace)::DecodeStrongWriteIntent` (for in-transaction reads) and `docdb::IntentToWriteRequest` (for transaction commits). 1. Create tests, specified in the test plan. Also, do the following: * Create new files defining helper functions related to row locks (row marks). * `src/yb/common/row_mark.cc` * `src/yb/common/row_mark.h` * Prevent `ROW_MARK_REFERENCE` and `ROW_MARK_COPY` from getting passed down as the `rowmark` execution parameter. * Update regress test `yb_pg_privileges` (java test `TestPgRegressAuthorization`) to uncomment `FOR UPDATE` row locking statements. Test Plan: * Jenkins * `./yb_build.sh` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.RowLockConflictMatrix` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SerializableDeleteForNoKeyUpdate` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SerializableDeleteForUpdate` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SerializableInsertForNoKeyUpdate` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SerializableInsertForUpdate` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SnapshotDeleteForNoKeyUpdate` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SnapshotDeleteForUpdate` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SnapshotInsertForNoKeyUpdate` * `--cxx-test pgwrapper_pg_mini-test --gtest_filter PgMiniTest.SnapshotInsertForUpdate` Reviewers: hector, sergei, mikhail Reviewed By: mikhail Subscribers: yql, bogdan Differential Revision: https://phabricator.dev.yugabyte.com/D7453
- Loading branch information
Jason Kim
committed
Nov 20, 2019
1 parent
6a8f17c
commit 0cfd0df
Showing
26 changed files
with
428 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,6 +99,7 @@ set(COMMON_SRCS | |
partial_row.cc | ||
partition.cc | ||
row_key-util.cc | ||
row_mark.cc | ||
schema.cc | ||
index.cc | ||
jsonb.cc | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// | ||
// Copyright (c) YugaByte, 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. | ||
// | ||
|
||
#include "yb/common/row_mark.h" | ||
|
||
#include <glog/logging.h> | ||
|
||
#include "yb/common/common.pb.h" | ||
#include "yb/gutil/macros.h" | ||
|
||
namespace yb { | ||
|
||
bool AreConflictingRowMarkTypes( | ||
const RowMarkType row_mark_type_a, | ||
const RowMarkType row_mark_type_b) { | ||
constexpr int kConflictThreshold = 4; | ||
const unsigned int value_a = static_cast<unsigned int>(row_mark_type_a); | ||
const unsigned int value_b = static_cast<unsigned int>(row_mark_type_b); | ||
|
||
// TODO: remove this when issue #2922 is fixed. | ||
if ((row_mark_type_a == RowMarkType::ROW_MARK_NOKEYEXCLUSIVE && | ||
row_mark_type_b == RowMarkType::ROW_MARK_KEYSHARE) || | ||
(row_mark_type_a == RowMarkType::ROW_MARK_KEYSHARE && | ||
row_mark_type_b == RowMarkType::ROW_MARK_NOKEYEXCLUSIVE)) { | ||
return true; | ||
} | ||
|
||
return (value_a + value_b < kConflictThreshold); | ||
} | ||
|
||
RowMarkType GetStrongestRowMarkType(std::initializer_list<RowMarkType> row_mark_types) { | ||
RowMarkType strongest_row_mark_type = RowMarkType::ROW_MARK_ABSENT; | ||
for (RowMarkType row_mark_type : row_mark_types) { | ||
strongest_row_mark_type = std::min(row_mark_type, strongest_row_mark_type); | ||
} | ||
return strongest_row_mark_type; | ||
} | ||
|
||
bool IsValidRowMarkType(RowMarkType row_mark_type) { | ||
switch (row_mark_type) { | ||
case RowMarkType::ROW_MARK_EXCLUSIVE: FALLTHROUGH_INTENDED; | ||
case RowMarkType::ROW_MARK_NOKEYEXCLUSIVE: FALLTHROUGH_INTENDED; | ||
case RowMarkType::ROW_MARK_SHARE: FALLTHROUGH_INTENDED; | ||
case RowMarkType::ROW_MARK_KEYSHARE: | ||
return true; | ||
break; | ||
default: | ||
return false; | ||
break; | ||
} | ||
} | ||
|
||
std::string RowMarkTypeToPgsqlString(const RowMarkType row_mark_type) { | ||
switch (row_mark_type) { | ||
case RowMarkType::ROW_MARK_EXCLUSIVE: | ||
return "UPDATE"; | ||
break; | ||
case RowMarkType::ROW_MARK_NOKEYEXCLUSIVE: | ||
return "NO KEY UPDATE"; | ||
break; | ||
case RowMarkType::ROW_MARK_SHARE: | ||
return "SHARE"; | ||
break; | ||
case RowMarkType::ROW_MARK_KEYSHARE: | ||
return "KEY SHARE"; | ||
break; | ||
default: | ||
// We shouldn't get here because other row lock types are disabled at the postgres level. | ||
LOG(DFATAL) << "Unsupported row lock of type " << RowMarkType_Name(row_mark_type); | ||
return ""; | ||
break; | ||
} | ||
} | ||
|
||
} // namespace yb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// | ||
// Copyright (c) YugaByte, 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. | ||
// | ||
#ifndef YB_COMMON_ROW_MARK_H | ||
#define YB_COMMON_ROW_MARK_H | ||
|
||
#include <glog/logging.h> | ||
|
||
#include "yb/common/common.pb.h" | ||
|
||
namespace yb { | ||
|
||
// Determine whether two row mark types conflict. | ||
bool AreConflictingRowMarkTypes(RowMarkType row_mark_type_a, RowMarkType row_mark_type_b); | ||
|
||
template <typename PB> | ||
RowMarkType GetRowMarkTypeFromPB(const PB& pb) { | ||
if (pb.has_row_mark_type()) { | ||
if (IsValidRowMarkType(pb.row_mark_type())) { | ||
return pb.row_mark_type(); | ||
} else { | ||
// We shouldn't get here because other row lock types are disabled at the postgres level. | ||
LOG(DFATAL) << "Unsupported row lock of type " << RowMarkType_Name(pb.row_mark_type()); | ||
} | ||
} | ||
return RowMarkType::ROW_MARK_ABSENT; | ||
} | ||
|
||
// Get the most restrictive row mark type from a list of row mark types. | ||
RowMarkType GetStrongestRowMarkType(std::initializer_list<RowMarkType> row_mark_types); | ||
|
||
// Determine whether a row mark type is valid. | ||
bool IsValidRowMarkType(RowMarkType row_mark_type); | ||
|
||
// Convert a row mark type to a string to use in a PostgreSQL query. | ||
std::string RowMarkTypeToPgsqlString(const RowMarkType row_mark_type); | ||
|
||
} // namespace yb | ||
|
||
#endif // YB_COMMON_ROW_MARK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.