[
https://issues.apache.org/jira/browse/HBASE-11126?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14009866#comment-14009866
]
Andrew Purtell commented on HBASE-11126:
----------------------------------------
Patch is looking good.
{code}
@@ -587,6 +587,25 @@ public interface RegionObserver extends Coprocessor {
void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
final Delete delete, final WALEdit edit, final Durability durability)
throws IOException;
+/**
+ * Called before the client updates the timestamp for delete Columns with
latest timestamp.
+ * <p>
+ * Call CoprocessorEnvironment#bypass to skip default actions
+ * <p>
+ * Call CoprocessorEnvironment#complete to skip any subsequent chained
+ * coprocessors
+ * @param c the environment provided by the region server
+ * @param mutation - the parent mutation associated with this delete cell
+ * @param cell - The deleteColumn with latest version cell
+ * @param byteNow - timestamp bytes
+ * @param family - family bytes
+ * @param get - the get formed using the current cell's row.
+ * Note that the get does not specify the family and qualifier
+ * @throws IOException
+ */
+ void preGetForDeleteVersion(final
ObserverContext<RegionCoprocessorEnvironment> c,
+ final Mutation mutation, final Cell cell, final byte[] byteNow, final
byte[] family,
+ final Get get) throws IOException;
{code}
preGetForDeleteVersion needs a better name. What are you doing with this new
hook?
In the Javadoc did you mean "Called before the *server* ... "
{code}
@@ -5064,12 +5090,18 @@ public class HRegion implements HeapSize { // ,
Writable{
rowLock = getRowLock(row);
try {
lock(this.updatesLock.readLock());
- // wait for all prior MVCC transactions to finish - while we hold the
row lock
- // (so that we are guaranteed to see the latest state)
- mvcc.completeMemstoreInsert(mvcc.beginMemstoreInsert());
- // now start my own transaction
- w = mvcc.beginMemstoreInsert();
try {
+ // wait for all prior MVCC transactions to finish - while we hold
the row lock
+ // (so that we are guaranteed to see the latest state)
+ mvcc.completeMemstoreInsert(mvcc.beginMemstoreInsert());
+ if (this.coprocessorHost != null) {
+ Result r = this.coprocessorHost.preAppendAfterRowLock(append);
+ if(r!= null) {
+ return r;
+ }
+ }
+ // now start my own transaction
+ w = mvcc.beginMemstoreInsert();
long now = EnvironmentEdgeManager.currentTimeMillis();
// Process each family
for (Map.Entry<byte[], List<Cell>> family :
append.getFamilyCellMap().entrySet()) {
{code}
Why are you moving completeMemstoreInsert and beginMemstoreInsert into the
inner try?
{code}
@@ -5254,12 +5286,18 @@ public class HRegion implements HeapSize { // ,
Writable{
RowLock rowLock = getRowLock(row);
try {
lock(this.updatesLock.readLock());
- // wait for all prior MVCC transactions to finish - while we hold the
row lock
- // (so that we are guaranteed to see the latest state)
- mvcc.completeMemstoreInsert(mvcc.beginMemstoreInsert());
- // now start my own transaction
- w = mvcc.beginMemstoreInsert();
try {
+ // wait for all prior MVCC transactions to finish - while we hold
the row lock
+ // (so that we are guaranteed to see the latest state)
+ mvcc.completeMemstoreInsert(mvcc.beginMemstoreInsert());
+ if (this.coprocessorHost != null) {
+ Result r =
this.coprocessorHost.preIncrementAfterRowLock(increment);
+ if (r != null) {
+ return r;
+ }
+ }
+ // now start my own transaction
+ w = mvcc.beginMemstoreInsert();
long now = EnvironmentEdgeManager.currentTimeMillis();
// Process each family
for (Map.Entry<byte [], List<Cell>> family:
{code}
Ditto.
{code}
diff --git
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
index 2e7b022..e0363b2 100644
---
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
+++
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
@@ -1730,7 +1730,7 @@ public class RSRpcServices implements
HBaseRPCErrorHandler,
ProtobufUtil.toComparator(condition.getComparator());
if (region.getCoprocessorHost() != null) {
processed = region.getCoprocessorHost().preCheckAndPut(
- row, family, qualifier, compareOp, comparator, put);
+ row, family, qualifier, compareOp, comparator, put);
}
if (processed == null) {
boolean result = region.checkAndMutate(row, family,
@@ -1758,7 +1758,7 @@ public class RSRpcServices implements
HBaseRPCErrorHandler,
ProtobufUtil.toComparator(condition.getComparator());
if (region.getCoprocessorHost() != null) {
processed = region.getCoprocessorHost().preCheckAndDelete(
- row, family, qualifier, compareOp, comparator, delete);
+ row, family, qualifier, compareOp, comparator, delete);
}
if (processed == null) {
boolean result = region.checkAndMutate(row, family,
{code}
Whitespace only changes, please remove.
> Add RegionObserver pre hooks that operate under row lock
> --------------------------------------------------------
>
> Key: HBASE-11126
> URL: https://issues.apache.org/jira/browse/HBASE-11126
> Project: HBase
> Issue Type: Improvement
> Affects Versions: 0.99.0, 0.98.3
> Reporter: Andrew Purtell
> Assignee: ramkrishna.s.vasudevan
> Attachments: HBASE-11126.patch, HBASE-11126_1.patch,
> HBASE-11126_new_2.patch, HBASE-11126_new_3.patch
>
>
> The coprocessor hooks were placed outside of row locks. This was meant to
> sidestep performance issues arising from significant work done within hook
> invocations. However as the security code increases in sophistication we are
> now running into concurrency issues trying to use them as a result of that
> early decision. Since the initial introduction of coprocessor upcalls there
> has been some significant refactoring done around them and concurrency
> control in core has become more complex. This is potentially an issue for
> many coprocessor users.
> We should do either:\\
> - Move all existing RegionObserver pre* hooks to execute under row lock.
> - Introduce a new set of RegionObserver pre* hooks that execute under row
> lock, named to indicate such.
> The second option is less likely to lead to surprises.
> All RegionObserver hook Javadoc should be updated with advice to the
> coprocessor implementor not to take their own row locks in the hook. If the
> current thread happens to already have a row lock and they try to take a lock
> on another row, there is a deadlock risk.
> As always a drawback of adding hooks is the potential for performance impact.
> We should benchmark the impact and decide if the second option above is a
> viable choice or if the first option is required.
> Finally, we should introduce a higher level interface for managing the
> registration of 'user' code for execution from the low level hooks. I filed
> HBASE-11125 to discuss this further.
--
This message was sent by Atlassian JIRA
(v6.2#6252)