diff --git a/bin/phoenix_sandbox.py b/bin/phoenix_sandbox.py
index 59608310098..2cbf05ad33a 100755
--- a/bin/phoenix_sandbox.py
+++ b/bin/phoenix_sandbox.py
@@ -25,7 +25,17 @@
import sys
import phoenix_utils
+# Since sandbox is used exclusively for development and debugging, it is easiest to
+# unconditionally enable tracing
+def set_sandbox_tracing():
+ global sandbox_trace_opts
+ sandbox_trace_opts = os.environ.get("PHOENIX_TRACE_OPTS")
+ if sandbox_trace_opts is None or phoenix_trace_opts == "":
+ sandbox_trace_opts = " -javaagent:" + phoenix_utils.opentelemetry_agent_jar + " -Dotel.metrics.exporter=none -Dotel.instrumentation.jdbc.enabled=false"
+ return ""
+
phoenix_utils.setPath()
+set_sandbox_tracing()
base_dir = os.path.join(phoenix_utils.current_dir, '..')
phoenix_target_dir = os.path.join(base_dir, 'phoenix-core', 'target')
@@ -44,9 +54,10 @@
with open(cp_file_path, 'r') as cp_file:
cp_components.append(cp_file.read())
-java_cmd = ("java $PHOENIX_OPTS -Dlog4j2.configurationFile=file:%s " +
- "-cp %s org.apache.phoenix.Sandbox") % (
- logging_config, ":".join(cp_components))
+java_cmd = ("java -Dlog4j2.configurationFile=file:%s " +
+ ' ' + sandbox_trace_opts + ' -Dotel.service.name="phoenix-sandbox" ' +
+ "-cp %s org.apache.phoenix.Sandbox") % (
+ logging_config, ":".join(cp_components))
proc = subprocess.Popen(java_cmd, shell=True)
try:
diff --git a/bin/phoenix_utils.py b/bin/phoenix_utils.py
index 404acc19ad1..da3bd7d3113 100755
--- a/bin/phoenix_utils.py
+++ b/bin/phoenix_utils.py
@@ -86,11 +86,14 @@ def setPath():
LOGGING_JAR_PATTERN2 = "log4j-api*.jar"
LOGGING_JAR_PATTERN3 = "log4j-1.2-api*.jar"
SQLLINE_WITH_DEPS_PATTERN = "sqlline-*-jar-with-dependencies.jar"
-
+ OPENTELEMETRY_AGENT_PATTERN = "opentelemetry-javaagent*.jar"
+ OPENTELEMETRY_AGENT_EXTENSION_PATTERN = "phoenix-opentelemetry-trace-sampler-*[!s].jar"
OVERRIDE_SLF4J_BACKEND = "OVERRIDE_SLF4J_BACKEND_JAR_LOCATION"
OVERRIDE_LOGGING = "OVERRIDE_LOGGING_JAR_LOCATION"
OVERRIDE_SQLLINE = "OVERRIDE_SQLLINE_JAR_LOCATION"
+ OVERRIDE_OPENTELEMETRY_AGENT = "OVERRIDE_OPENTELEMETRY_AGENT_JAR_LOCATION"
+ OVERRIDE_OPENTELEMETRY_AGENT_EXTENSION = "OVERRIDE_OPENTELEMETRY_AGENT_EXTENSION_JAR_LOCATION"
# Backward support old env variable PHOENIX_LIB_DIR replaced by PHOENIX_CLASS_PATH
global phoenix_class_path
@@ -185,12 +188,34 @@ def setPath():
global logging_jar
logging_jar = os.environ.get(OVERRIDE_LOGGING)
if logging_jar is None or logging_jar == "":
- logging_jar = findFileInPathWithoutRecursion(LOGGING_JAR_PATTERN, os.path.join(current_dir, "..","lib"))
- logging_jar += ":"+findFileInPathWithoutRecursion(LOGGING_JAR_PATTERN2, os.path.join(current_dir, "..","lib"))
- logging_jar += ":"+findFileInPathWithoutRecursion(LOGGING_JAR_PATTERN3, os.path.join(current_dir, "..","lib"))
+ logging_jar = findFileInPathWithoutRecursion(LOGGING_JAR_PATTERN, os.path.join(current_dir, "..", "lib"))
+ logging_jar += ":"+findFileInPathWithoutRecursion(LOGGING_JAR_PATTERN2, os.path.join(current_dir, "..", "lib"))
+ logging_jar += ":"+findFileInPathWithoutRecursion(LOGGING_JAR_PATTERN3, os.path.join(current_dir, "..", "lib"))
+
+ global opentelemetry_agent_jar
+ opentelemetry_agent_jar = os.environ.get(OVERRIDE_OPENTELEMETRY_AGENT)
+ if opentelemetry_agent_jar is None or opentelemetry_agent_jar == "":
+ opentelemetry_agent_jar = findFileInPathWithoutRecursion(OPENTELEMETRY_AGENT_PATTERN, os.path.join(current_dir, "..", "lib/tracing"))
+ global opentelemetry_agent_extension_jar
+ opentelemetry_agent_extension_jar = os.environ.get(OVERRIDE_OPENTELEMETRY_AGENT_EXTENSION)
+ if opentelemetry_agent_extension_jar is None or opentelemetry_agent_extension_jar == "":
+ opentelemetry_agent_extension_jar = findFileInPathWithoutRecursion(OPENTELEMETRY_AGENT_EXTENSION_PATTERN, os.path.join(current_dir, "..", "lib/tracing"))
+ if opentelemetry_agent_extension_jar is None or opentelemetry_agent_extension_jar == "":
+ opentelemetry_agent_extension_jar = findFileInPathWithoutRecursion(OPENTELEMETRY_AGENT_EXTENSION_PATTERN, os.path.join(current_dir, "..", "phoenix-opentelemetry-trace-sampler", "target"))
return ""
+
+def set_tracing():
+ global phoenix_trace_opts
+ phoenix_trace_opts = os.environ.get("PHOENIX_TRACE_OPTS")
+ if phoenix_trace_opts is None or phoenix_trace_opts == "":
+ phoenix_trace_opts = " -javaagent:" + opentelemetry_agent_jar + \
+ " -Dotel.javaagent.extensions=" + opentelemetry_agent_extension_jar + \
+ " -Dotel.metrics.exporter=none -Dotel.instrumentation.jdbc.enabled=false -Dotel.traces.sampler=phoenix_hintable_sampler "
+ return ""
+
+
def shell_quote(args):
"""
Return the platform specific shell quoted string. Handles Windows and *nix platforms.
@@ -212,6 +237,9 @@ def common_sqlline_args(parser):
parser.add_argument('-fc', '--fastconnect',
help='Fetch all schemas on initial connection',
action="store_true")
+ parser.add_argument('--trace', help='Load and set up Opentelemetry agent',
+ action="store_true")
+ parser.add_argument('--traceratio', help='Default trace ratio')
if __name__ == "__main__":
setPath()
@@ -226,3 +254,6 @@ def common_sqlline_args(parser):
print("sqlline_with_deps_jar:", sqlline_with_deps_jar)
print("slf4j_backend_jar:", slf4j_backend_jar)
print("logging_jar:", logging_jar)
+ print("opentelemetry_agent_jar:", opentelemetry_agent_jar)
+ print("opentelemetry_agent_extension_jar:", opentelemetry_agent_extension_jar)
+
diff --git a/bin/sqlline.py b/bin/sqlline.py
index 72b06bdab70..c576e0e9ac7 100755
--- a/bin/sqlline.py
+++ b/bin/sqlline.py
@@ -46,6 +46,7 @@ def kill_child():
atexit.register(kill_child)
phoenix_utils.setPath()
+phoenix_utils.set_tracing()
parser = argparse.ArgumentParser(description='Launches the Apache Phoenix Client.')
# Positional argument 'zookeepers' is optional. The PhoenixDriver will automatically populate
@@ -123,6 +124,8 @@ def kill_child():
else:
disable_jna = ""
+x = ( 'a' 'b')
+
java_cmd = java + ' $PHOENIX_OPTS ' + \
' -cp "' + phoenix_utils.hbase_conf_dir + os.pathsep + \
phoenix_utils.hadoop_conf + os.pathsep + \
@@ -132,13 +135,14 @@ def kill_child():
phoenix_utils.phoenix_client_embedded_jar + \
'" -Dlog4j2.configurationFile=file:' + os.path.join(phoenix_utils.current_dir, "log4j2.properties") + \
disable_jna + \
- " sqlline.SqlLine -d org.apache.phoenix.jdbc.PhoenixDriver" + \
- (not args.noconnect and " -u " + phoenix_utils.shell_quote([jdbc_url]) or "") + \
- " -n none -p none --color=" + \
- (args.color and "true" or "false") + \
- " --fastConnect=" + (args.fastconnect and "true" or "false") + \
- " --verbose=" + (args.verbose and "true" or "false") + \
- " --incremental=false --isolation=TRANSACTION_READ_COMMITTED " + sqlfile
+ ((phoenix_utils.phoenix_trace_opts + ' -Dotel.service.name="phoenix-sqlline" ') if args.trace else "" ) + \
+ ("" if args.traceratio is None else "-Dotel.traces.sampler.arg=" + args.traceratio) + \
+ " sqlline.SqlLine -d org.apache.phoenix.jdbc.PhoenixDriver " + \
+ ("" if args.noconnect else (" -u " + phoenix_utils.shell_quote([jdbc_url]))) + \
+ " -n none -p none --color=" + ("true" if args.color else "false") + \
+ " --fastConnect=" + ("true" if args.fastconnect else "false") + \
+ " --verbose=" + ( "true" if args.verbose else "false") + \
+ " --incremental=false --isolation=TRANSACTION_READ_COMMITTED " + sqlfile
if args.verbose_command:
print("Executing java command: " + java_cmd)
diff --git a/phoenix-assembly/pom.xml b/phoenix-assembly/pom.xml
index 52d337618fb..cedcdbf06c3 100644
--- a/phoenix-assembly/pom.xml
+++ b/phoenix-assembly/pom.xml
@@ -155,11 +155,11 @@
org.apache.phoenix
- phoenix-pherf
+ phoenix-opentelemetry-trace-samplerorg.apache.phoenix
- phoenix-tracing-webapp
+ phoenix-pherfsqlline
@@ -167,7 +167,26 @@
${sqlline.version}jar-with-dependencies
-
+
+ io.opentelemetry.javaagent
+ opentelemetry-javaagent
+
+
+ org.apache.logging.log4j
+ log4j-api
+
+
+ org.apache.logging.log4j
+ log4j-core
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+
+
+ org.apache.logging.log4j
+ log4j-1.2-api
+
@@ -206,11 +225,6 @@
phoenix-shaded-guava${phoenix.thirdparty.version}
-
- org.apache.phoenix
- phoenix-tracing-webapp
- ${project.version}
- org.apache.phoenixphoenix-hbase-compat-2.4.0
diff --git a/phoenix-assembly/src/build/components/all-common-dependencies.xml b/phoenix-assembly/src/build/components/all-common-dependencies.xml
index 4a5fd9bf865..52d0e14c010 100644
--- a/phoenix-assembly/src/build/components/all-common-dependencies.xml
+++ b/phoenix-assembly/src/build/components/all-common-dependencies.xml
@@ -30,5 +30,12 @@
org.apache.logging.log4j:log4j-1.2-api
+
+ false
+ /lib/tracing
+
+ io.opentelemetry.javaagent:opentelemetry-javaagent
+
+
\ No newline at end of file
diff --git a/phoenix-assembly/src/build/components/all-common-jars.xml b/phoenix-assembly/src/build/components/all-common-jars.xml
index 1a6abd31936..ec1dd0626ff 100644
--- a/phoenix-assembly/src/build/components/all-common-jars.xml
+++ b/phoenix-assembly/src/build/components/all-common-jars.xml
@@ -47,5 +47,14 @@
phoenix-pherf.jar
+
+ ${project.basedir}/../phoenix-opentelemetry-trace-sampler/target
+
+ /lib/tracing/
+
+
+ phoenix-opentelemetry-trace-sampler-${project.version}.jar
+
+
diff --git a/phoenix-client-parent/phoenix-client-embedded/pom.xml b/phoenix-client-parent/phoenix-client-embedded/pom.xml
index 50cecce5128..812911ac7a9 100644
--- a/phoenix-client-parent/phoenix-client-embedded/pom.xml
+++ b/phoenix-client-parent/phoenix-client-embedded/pom.xml
@@ -94,6 +94,10 @@
phoenix-hbase-compat-${hbase.compat.version}false
+
+ org.apache.phoenix
+ phoenix-opentelemetry-trace-sampler
+ org.eclipse.jetty
diff --git a/phoenix-client-parent/pom.xml b/phoenix-client-parent/pom.xml
index 42bee5c047d..1450d192bd9 100644
--- a/phoenix-client-parent/pom.xml
+++ b/phoenix-client-parent/pom.xml
@@ -184,6 +184,8 @@
io/${shaded.package}.io.
+
+ io.opentelemetry/**io/compression/**io/mapfile/**
diff --git a/phoenix-core/pom.xml b/phoenix-core/pom.xml
index 7827a065f0d..66c15706c93 100644
--- a/phoenix-core/pom.xml
+++ b/phoenix-core/pom.xml
@@ -214,6 +214,21 @@
${project.basedir}/../lib
+
+ copy-otel-agent-for-sqlline
+
+ copy
+
+
+
+
+ io.opentelemetry.javaagent
+ opentelemetry-javaagent
+
+
+ ${project.basedir}/../lib/tracing
+
+
@@ -500,10 +515,6 @@
com.google.protobufprotobuf-java
-
- org.apache.htrace
- htrace-core
- org.slf4jslf4j-api
@@ -569,6 +580,18 @@
org.hdrhistogramHdrHistogram
+
+ io.opentelemetry
+ opentelemetry-api
+
+
+ io.opentelemetry
+ opentelemetry-context
+
+
+ io.opentelemetry
+ opentelemetry-semconv
+
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java
index 447926ecedc..33fb3ba283e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/BaseTracingTestIT.java
@@ -29,13 +29,8 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import org.apache.htrace.Span;
-import org.apache.htrace.Trace;
-import org.apache.htrace.impl.MilliSpan;
import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
import org.apache.phoenix.jdbc.DelegateConnection;
-import org.apache.phoenix.trace.util.Tracing;
-import org.apache.phoenix.trace.util.Tracing.Frequency;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.PropertiesUtil;
import org.junit.After;
@@ -49,131 +44,93 @@
*/
public abstract class BaseTracingTestIT extends ParallelStatsDisabledIT {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(BaseTracingTestIT.class);
-
- protected CountDownLatch latch;
- protected int defaultTracingThreadPoolForTest = 1;
- protected int defaultTracingBatchSizeForTest = 1;
- protected String tracingTableName;
- protected TraceSpanReceiver traceSpanReceiver = null;
- protected TestTraceWriter testTraceWriter = null;
-
- @Before
- public void setup() {
- tracingTableName = "TRACING_" + generateUniqueName();
- traceSpanReceiver = new TraceSpanReceiver();
- Trace.addReceiver(traceSpanReceiver);
- testTraceWriter =
- new TestTraceWriter(tracingTableName, defaultTracingThreadPoolForTest,
- defaultTracingBatchSizeForTest);
- }
-
- @After
- public void cleanUp() {
- Trace.removeReceiver(traceSpanReceiver);
- if (testTraceWriter != null) testTraceWriter.stop();
- }
-
- public static Connection getConnectionWithoutTracing() throws SQLException {
- Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
- return getConnectionWithoutTracing(props);
- }
-
- public static Connection getConnectionWithoutTracing(Properties props) throws SQLException {
- Connection conn = getConnectionWithTracingFrequency(props, Frequency.NEVER);
- return conn;
- }
-
- public static Connection getTracingConnection() throws Exception {
- return getTracingConnection(Collections. emptyMap(), null);
- }
-
- public static Connection getTracingConnection(Map customAnnotations,
- String tenantId) throws Exception {
- Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
- for (Map.Entry annot : customAnnotations.entrySet()) {
- props.put(ANNOTATION_ATTRIB_PREFIX + annot.getKey(), annot.getValue());
- }
- if (tenantId != null) {
- props.put(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
- }
- return getConnectionWithTracingFrequency(props, Tracing.Frequency.ALWAYS);
- }
-
- public static Connection getConnectionWithTracingFrequency(Properties props,
- Tracing.Frequency frequency) throws SQLException {
- Tracing.setSampling(props, frequency);
- return DriverManager.getConnection(getUrl(), props);
- }
-
- protected Span createNewSpan(long traceid, long parentid, long spanid, String description,
- long startTime, long endTime, String processid, String... tags) {
-
- Span span =
- new MilliSpan.Builder().description(description).traceId(traceid)
- .parents(new long[] { parentid }).spanId(spanid).processId(processid)
- .begin(startTime).end(endTime).build();
-
- int tagCount = 0;
- for (String annotation : tags) {
- span.addKVAnnotation((Integer.toString(tagCount++)).getBytes(), annotation.getBytes());
- }
- return span;
- }
-
- private static class CountDownConnection extends DelegateConnection {
- private CountDownLatch commit;
-
- public CountDownConnection(Connection conn, CountDownLatch commit) {
- super(conn);
- this.commit = commit;
- }
-
- @Override
- public void commit() throws SQLException {
- super.commit();
- commit.countDown();
- }
-
- }
-
- protected class TestTraceWriter extends TraceWriter {
-
- public TestTraceWriter(String tableName, int numThreads, int batchSize) {
- super(tableName, numThreads, batchSize);
- }
-
- @Override
- protected Connection getConnection(String tableName) {
- try {
- Connection connection =
- new CountDownConnection(getConnectionWithoutTracing(), latch);
- if (!traceTableExists(connection, tableName)) {
- createTable(connection, tableName);
- }
- return connection;
- } catch (SQLException e) {
- LOGGER.error("New connection failed for tracing Table: " + tableName, e);
- return null;
- }
- }
-
- @Override
- protected TraceSpanReceiver getTraceSpanReceiver() {
- return traceSpanReceiver;
- }
-
- public void stop() {
- if (executor == null) return;
- try {
- executor.shutdownNow();
- executor.awaitTermination(5, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- LOGGER.error("Failed to stop the thread. ", e);
- }
- }
-
- }
+//
+// private static final Logger LOGGER = LoggerFactory.getLogger(BaseTracingTestIT.class);
+//
+// protected CountDownLatch latch;
+// protected int defaultTracingThreadPoolForTest = 1;
+// protected int defaultTracingBatchSizeForTest = 1;
+// protected String tracingTableName;
+// protected TraceSpanReceiver traceSpanReceiver = null;
+// protected TestTraceWriter testTraceWriter = null;
+//
+// @Before
+// public void setup() {
+// tracingTableName = "TRACING_" + generateUniqueName();
+// traceSpanReceiver = new TraceSpanReceiver();
+// Trace.addReceiver(traceSpanReceiver);
+// testTraceWriter =
+// new TestTraceWriter(tracingTableName, defaultTracingThreadPoolForTest,
+// defaultTracingBatchSizeForTest);
+// }
+//
+// @After
+// public void cleanUp() {
+// Trace.removeReceiver(traceSpanReceiver);
+// if (testTraceWriter != null) testTraceWriter.stop();
+// }
+//
+// public static Connection getConnectionWithoutTracing() throws SQLException {
+// Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+// return getConnectionWithoutTracing(props);
+// }
+//
+// public static Connection getConnectionWithoutTracing(Properties props) throws SQLException {
+// Connection conn = getConnectionWithTracingFrequency(props, Frequency.NEVER);
+// return conn;
+// }
+//
+// public static Connection getTracingConnection() throws Exception {
+// return getTracingConnection(Collections. emptyMap(), null);
+// }
+//
+// public static Connection getTracingConnection(Map customAnnotations,
+// String tenantId) throws Exception {
+// Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+// for (Map.Entry annot : customAnnotations.entrySet()) {
+// props.put(ANNOTATION_ATTRIB_PREFIX + annot.getKey(), annot.getValue());
+// }
+// if (tenantId != null) {
+// props.put(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
+// }
+// return getConnectionWithTracingFrequency(props, Tracing.Frequency.ALWAYS);
+// }
+//
+// public static Connection getConnectionWithTracingFrequency(Properties props,
+// Tracing.Frequency frequency) throws SQLException {
+// Tracing.setSampling(props, frequency);
+// return DriverManager.getConnection(getUrl(), props);
+// }
+//
+// protected Span createNewSpan(long traceid, long parentid, long spanid, String description,
+// long startTime, long endTime, String processid, String... tags) {
+//
+// Span span =
+// new MilliSpan.Builder().description(description).traceId(traceid)
+// .parents(new long[] { parentid }).spanId(spanid).processId(processid)
+// .begin(startTime).end(endTime).build();
+//
+// int tagCount = 0;
+// for (String annotation : tags) {
+// span.addKVAnnotation((Integer.toString(tagCount++)).getBytes(), annotation.getBytes());
+// }
+// return span;
+// }
+//
+// private static class CountDownConnection extends DelegateConnection {
+// private CountDownLatch commit;
+//
+// public CountDownConnection(Connection conn, CountDownLatch commit) {
+// super(conn);
+// this.commit = commit;
+// }
+//
+// @Override
+// public void commit() throws SQLException {
+// super.commit();
+// commit.countDown();
+// }
+//
+// }
}
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java
deleted file mode 100644
index 2508a3152a2..00000000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTableMetricsWriterIT.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-package org.apache.phoenix.trace;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.sql.Connection;
-import java.util.Collection;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.htrace.Span;
-import org.apache.htrace.Tracer;
-import org.apache.phoenix.end2end.ParallelStatsDisabledTest;
-import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.trace.TraceReader.SpanInfo;
-import org.apache.phoenix.trace.TraceReader.TraceHolder;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-/**
- * Test that the logging sink stores the expected metrics/stats
- */
-@Category(ParallelStatsDisabledTest.class)
-public class PhoenixTableMetricsWriterIT extends BaseTracingTestIT {
-
- /**
- * IT should create the target table if it hasn't been created yet, but not fail if the table
- * has already been created
- * @throws Exception on failure
- */
- @Test
- public void testCreatesTable() throws Exception {
-
- Connection conn = getConnectionWithoutTracing();
-
- // check for existence of the tracing table
- try {
- String ddl = "CREATE TABLE " + QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME;
- conn.createStatement().execute(ddl);
- fail("Table " + QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME
- + " was not created by the metrics sink");
- } catch (Exception e) {
- // expected
- }
- }
-
- /**
- * Simple metrics writing and reading check, that uses the standard wrapping in the
- * {@link TraceWriter}
- * @throws Exception on failure
- */
- @Test
- public void writeMetrics() throws Exception {
-
- Connection conn = getConnectionWithoutTracing();
- latch = new CountDownLatch(1);
- testTraceWriter.start();
-
- // create a simple metrics record
- long traceid = 987654;
- String description = "Some generic trace";
- long spanid = 10;
- long parentid = 11;
- long startTime = 12;
- long endTime = 13;
- String processid = "Some process";
- String annotation = "test annotation for a span";
-
- Span span = createNewSpan(traceid, parentid, spanid, description, startTime, endTime,
- processid, annotation);
-
- Tracer.getInstance().deliver(span);
- assertTrue("Span never committed to table", latch.await(30, TimeUnit.SECONDS));
-
- // make sure we only get expected stat entry (matcing the trace id), otherwise we could the
- // stats for the update as well
- TraceReader reader = new TraceReader(conn, tracingTableName);
- Collection traces = reader.readAll(10);
- assertEquals("Wrong number of traces in the tracing table", 1, traces.size());
-
- // validate trace
- TraceHolder trace = traces.iterator().next();
- // we are just going to get an orphan span b/c we don't send in a parent
- assertEquals("Didn't get expected orphaned spans!" + trace.orphans, 1, trace.orphans.size());
-
- assertEquals(traceid, trace.traceid);
- SpanInfo spanInfo = trace.orphans.get(0);
- assertEquals(description, spanInfo.description);
- assertEquals(parentid, spanInfo.getParentIdForTesting());
- assertEquals(startTime, spanInfo.start);
- assertEquals(endTime, spanInfo.end);
- assertEquals("Wrong number of tags", 0, spanInfo.tagCount);
- assertEquals("Wrong number of annotations", 1, spanInfo.annotationCount);
- }
-
-}
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java
index 69cf26ded34..9796acb7f92 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTracingEndToEndIT.java
@@ -32,13 +32,9 @@
import java.util.concurrent.TimeUnit;
import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.htrace.*;
-import org.apache.htrace.impl.ProbabilitySampler;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
import org.apache.phoenix.end2end.ParallelStatsDisabledTest;
import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.trace.TraceReader.SpanInfo;
-import org.apache.phoenix.trace.TraceReader.TraceHolder;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -54,534 +50,534 @@
@Category(ParallelStatsDisabledTest.class)
@Ignore("Will need to revisit for new HDFS/HBase/HTrace, broken on 5.x")
public class PhoenixTracingEndToEndIT extends BaseTracingTestIT {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(PhoenixTracingEndToEndIT.class);
- private static final int MAX_RETRIES = 10;
- private String enabledForLoggingTable;
- private String enableForLoggingIndex;
-
- @Before
- public void setupMetrics() throws Exception {
- enabledForLoggingTable = "ENABLED_FOR_LOGGING_" + generateUniqueName();
- enableForLoggingIndex = "ENABALED_FOR_LOGGING_INDEX_" + generateUniqueName();
- }
-
- /**
- * Simple test that we can correctly write spans to the phoenix table
- * @throws Exception on failure
- */
- @Test
- public void testWriteSpans() throws Exception {
-
- LOGGER.info("testWriteSpans TableName: " + tracingTableName);
- // watch our sink so we know when commits happen
- latch = new CountDownLatch(1);
-
- testTraceWriter.start();
-
- // write some spans
- TraceScope trace = Trace.startSpan("Start write test", Sampler.ALWAYS);
- Span span = trace.getSpan();
-
- // add a child with some annotations
- Span child = span.child("child 1");
- child.addTimelineAnnotation("timeline annotation");
- TracingUtils.addAnnotation(child, "test annotation", 10);
- child.stop();
-
- // sleep a little bit to get some time difference
- Thread.sleep(100);
-
- trace.close();
-
- // pass the trace on
- Tracer.getInstance().deliver(span);
-
- // wait for the tracer to actually do the write
- assertTrue("Sink not flushed. commit() not called on the connection", latch.await(60, TimeUnit.SECONDS));
-
- // look for the writes to make sure they were made
- Connection conn = getConnectionWithoutTracing();
- checkStoredTraces(conn, new TraceChecker() {
- @Override
- public boolean foundTrace(TraceHolder trace, SpanInfo info) {
- if (info.description.equals("child 1")) {
- assertEquals("Not all annotations present", 1, info.annotationCount);
- assertEquals("Not all tags present", 1, info.tagCount);
- boolean found = false;
- for (String annotation : info.annotations) {
- if (annotation.startsWith("test annotation")) {
- found = true;
- }
- }
- assertTrue("Missing the annotations in span: " + info, found);
- found = false;
- for (String tag : info.tags) {
- if (tag.endsWith("timeline annotation")) {
- found = true;
- }
- }
- assertTrue("Missing the tags in span: " + info, found);
- return true;
- }
- return false;
- }
- });
- }
-
- /**
- * Test that span will actually go into the this sink and be written on both side of the wire,
- * through the indexing code.
- * @throws Exception
- */
- @Test
- public void testClientServerIndexingTracing() throws Exception {
-
- LOGGER.info("testClientServerIndexingTracing TableName: " + tracingTableName);
- // one call for client side, one call for server side
- latch = new CountDownLatch(2);
- testTraceWriter.start();
-
- // separate connection so we don't create extra traces
- Connection conn = getConnectionWithoutTracing();
- createTestTable(conn, true);
-
- // trace the requests we send
- Connection traceable = getTracingConnection();
- LOGGER.debug("Doing dummy the writes to the tracked table");
- String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
- PreparedStatement stmt = traceable.prepareStatement(insert);
- stmt.setString(1, "key1");
- stmt.setLong(2, 1);
- // this first trace just does a simple open/close of the span. Its not doing anything
- // terribly interesting because we aren't auto-committing on the connection, so it just
- // updates the mutation state and returns.
- stmt.execute();
- stmt.setString(1, "key2");
- stmt.setLong(2, 2);
- stmt.execute();
- traceable.commit();
-
- // wait for the latch to countdown, as the metrics system is time-based
- LOGGER.debug("Waiting for latch to complete!");
- latch.await(200, TimeUnit.SECONDS);// should be way more than GC pauses
-
- // read the traces back out
-
- /* Expected:
- * 1. Single element trace - for first PreparedStatement#execute span
- * 2. Two element trace for second PreparedStatement#execute span
- * a. execute call
- * b. metadata lookup*
- * 3. Commit trace.
- * a. Committing to tables
- * i. Committing to single table
- * ii. hbase batch write*
- * i.I. span on server
- * i.II. building index updates
- * i.III. waiting for latch
- * where '*' is a generically named thread (e.g phoenix-1-thread-X)
- */
- boolean indexingCompleted = checkStoredTraces(conn, new TraceChecker() {
- @Override
- public boolean foundTrace(TraceHolder trace, SpanInfo span) {
- String traceInfo = trace.toString();
- // skip logging traces that are just traces about tracing
- if (traceInfo.contains(tracingTableName)) {
- return false;
- }
- return traceInfo.contains("Completing index");
- }
- });
-
- assertTrue("Never found indexing updates", indexingCompleted);
- }
-
- private void createTestTable(Connection conn, boolean withIndex) throws SQLException {
- // create a dummy table
- String ddl =
- "create table if not exists " + enabledForLoggingTable + "(" + "k varchar not null, " + "c1 bigint"
- + " CONSTRAINT pk PRIMARY KEY (k))";
- conn.createStatement().execute(ddl);
-
- // early exit if we don't need to create an index
- if (!withIndex) {
- return;
- }
- // create an index on the table - we know indexing has some basic tracing
- ddl = "CREATE INDEX IF NOT EXISTS " + enableForLoggingIndex + " on " + enabledForLoggingTable + " (c1)";
- conn.createStatement().execute(ddl);
- }
-
- @Test
- public void testScanTracing() throws Exception {
-
- LOGGER.info("testScanTracing TableName: " + tracingTableName);
-
- // separate connections to minimize amount of traces that are generated
- Connection traceable = getTracingConnection();
- Connection conn = getConnectionWithoutTracing();
-
- // one call for client side, one call for server side
- latch = new CountDownLatch(2);
- testTraceWriter.start();
-
- // create a dummy table
- createTestTable(conn, false);
-
- // update the table, but don't trace these, to simplify the traces we read
- LOGGER.debug("Doing dummy the writes to the tracked table");
- String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
- PreparedStatement stmt = conn.prepareStatement(insert);
- stmt.setString(1, "key1");
- stmt.setLong(2, 1);
- stmt.execute();
- conn.commit();
- conn.rollback();
-
- // setup for next set of updates
- stmt.setString(1, "key2");
- stmt.setLong(2, 2);
- stmt.execute();
- conn.commit();
- conn.rollback();
-
- // do a scan of the table
- String read = "SELECT * FROM " + enabledForLoggingTable;
- ResultSet results = traceable.createStatement().executeQuery(read);
- assertTrue("Didn't get first result", results.next());
- assertTrue("Didn't get second result", results.next());
- results.close();
-
- assertTrue("Get expected updates to trace table", latch.await(200, TimeUnit.SECONDS));
- // don't trace reads either
- boolean tracingComplete = checkStoredTraces(conn, new TraceChecker(){
-
- @Override
- public boolean foundTrace(TraceHolder currentTrace) {
- String traceInfo = currentTrace.toString();
- return traceInfo.contains("Parallel scanner");
- }
- });
- assertTrue("Didn't find the parallel scanner in the tracing", tracingComplete);
- }
-
- @Test
- public void testScanTracingOnServer() throws Exception {
-
- LOGGER.info("testScanTracingOnServer TableName: " + tracingTableName);
-
- // separate connections to minimize amount of traces that are generated
- Connection traceable = getTracingConnection();
- Connection conn = getConnectionWithoutTracing();
-
- // one call for client side, one call for server side
- latch = new CountDownLatch(5);
- testTraceWriter.start();
-
- // create a dummy table
- createTestTable(conn, false);
-
- // update the table, but don't trace these, to simplify the traces we read
- LOGGER.debug("Doing dummy the writes to the tracked table");
- String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
- PreparedStatement stmt = conn.prepareStatement(insert);
- stmt.setString(1, "key1");
- stmt.setLong(2, 1);
- stmt.execute();
- conn.commit();
-
- // setup for next set of updates
- stmt.setString(1, "key2");
- stmt.setLong(2, 2);
- stmt.execute();
- conn.commit();
-
- // do a scan of the table
- String read = "SELECT COUNT(*) FROM " + enabledForLoggingTable;
- ResultSet results = traceable.createStatement().executeQuery(read);
- assertTrue("Didn't get count result", results.next());
- // make sure we got the expected count
- assertEquals("Didn't get the expected number of row", 2, results.getInt(1));
- results.close();
-
- assertTrue("Didn't get expected updates to trace table", latch.await(60, TimeUnit.SECONDS));
-
- // don't trace reads either
- boolean found = checkStoredTraces(conn, new TraceChecker() {
- @Override
- public boolean foundTrace(TraceHolder trace) {
- String traceInfo = trace.toString();
- return traceInfo.contains(BaseScannerRegionObserver.SCANNER_OPENED_TRACE_INFO);
- }
- });
- assertTrue("Didn't find the parallel scanner in the tracing", found);
- }
-
- @Test
- public void testCustomAnnotationTracing() throws Exception {
-
- LOGGER.info("testCustomAnnotationTracing TableName: " + tracingTableName);
-
- final String customAnnotationKey = "myannot";
- final String customAnnotationValue = "a1";
- final String tenantId = "tenant1";
- // separate connections to minimize amount of traces that are generated
- Connection traceable = getTracingConnection(ImmutableMap.of(customAnnotationKey, customAnnotationValue), tenantId);
- Connection conn = getConnectionWithoutTracing();
-
- // one call for client side, one call for server side
- latch = new CountDownLatch(2);
- testTraceWriter.start();
-
- // create a dummy table
- createTestTable(conn, false);
-
- // update the table, but don't trace these, to simplify the traces we read
- LOGGER.debug("Doing dummy the writes to the tracked table");
- String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
- PreparedStatement stmt = conn.prepareStatement(insert);
- stmt.setString(1, "key1");
- stmt.setLong(2, 1);
- stmt.execute();
- conn.commit();
- conn.rollback();
-
- // setup for next set of updates
- stmt.setString(1, "key2");
- stmt.setLong(2, 2);
- stmt.execute();
- conn.commit();
- conn.rollback();
-
- // do a scan of the table
- String read = "SELECT * FROM " + enabledForLoggingTable;
- ResultSet results = traceable.createStatement().executeQuery(read);
- assertTrue("Didn't get first result", results.next());
- assertTrue("Didn't get second result", results.next());
- results.close();
-
- assertTrue("Get expected updates to trace table", latch.await(200, TimeUnit.SECONDS));
-
- assertAnnotationPresent(customAnnotationKey, customAnnotationValue, conn);
- assertAnnotationPresent(TENANT_ID_ATTRIB, tenantId, conn);
- // CurrentSCN is also added as an annotation. Not tested here because it screws up test setup.
- }
-
- @Test
- public void testTraceOnOrOff() throws Exception {
- Connection conn1 = getConnectionWithoutTracing(); //DriverManager.getConnection(getUrl());
- try{
- Statement statement = conn1.createStatement();
- ResultSet rs = statement.executeQuery("TRACE ON");
- assertTrue(rs.next());
- PhoenixConnection pconn = (PhoenixConnection) conn1;
- long traceId = pconn.getTraceScope().getSpan().getTraceId();
- assertEquals(traceId, rs.getLong(1));
- assertEquals(traceId, rs.getLong("trace_id"));
- assertFalse(rs.next());
- assertEquals(Sampler.ALWAYS, pconn.getSampler());
-
- rs = statement.executeQuery("TRACE OFF");
- assertTrue(rs.next());
- assertEquals(traceId, rs.getLong(1));
- assertEquals(traceId, rs.getLong("trace_id"));
- assertFalse(rs.next());
- assertEquals(Sampler.NEVER, pconn.getSampler());
-
- rs = statement.executeQuery("TRACE OFF");
- assertFalse(rs.next());
-
- rs = statement.executeQuery("TRACE ON WITH SAMPLING 0.5");
- rs.next();
- assertTrue(((PhoenixConnection) conn1).getSampler() instanceof ProbabilitySampler);
-
- rs = statement.executeQuery("TRACE ON WITH SAMPLING 1.0");
- assertTrue(rs.next());
- traceId = pconn.getTraceScope().getSpan()
- .getTraceId();
- assertEquals(traceId, rs.getLong(1));
- assertEquals(traceId, rs.getLong("trace_id"));
- assertFalse(rs.next());
- assertEquals(Sampler.ALWAYS, pconn.getSampler());
-
- rs = statement.executeQuery("TRACE ON WITH SAMPLING 0.5");
- rs.next();
- assertTrue(((PhoenixConnection) conn1).getSampler() instanceof ProbabilitySampler);
-
- rs = statement.executeQuery("TRACE ON WITH SAMPLING 0.0");
- rs.next();
- assertEquals(Sampler.NEVER, pconn.getSampler());
-
- rs = statement.executeQuery("TRACE OFF");
- assertFalse(rs.next());
-
- } finally {
- conn1.close();
- }
- }
-
- @Test
- public void testSingleSpan() throws Exception {
-
- LOGGER.info("testSingleSpan TableName: " + tracingTableName);
-
- Properties props = new Properties(TEST_PROPERTIES);
- Connection conn = DriverManager.getConnection(getUrl(), props);
- latch = new CountDownLatch(1);
- testTraceWriter.start();
-
- // create a simple metrics record
- long traceid = 987654;
- Span span = createNewSpan(traceid, Span.ROOT_SPAN_ID, 10, "root", 12, 13, "Some process", "test annotation for a span");
-
- Tracer.getInstance().deliver(span);
- assertTrue("Updates not written in table", latch.await(60, TimeUnit.SECONDS));
-
- // start a reader
- validateTraces(Collections.singletonList(span), conn, traceid, tracingTableName);
- }
-
- /**
- * Test multiple spans, within the same trace. Some spans are independent of the parent span,
- * some are child spans
- * @throws Exception on failure
- */
- @Test
- public void testMultipleSpans() throws Exception {
-
- LOGGER.info("testMultipleSpans TableName: " + tracingTableName);
-
- Connection conn = getConnectionWithoutTracing();
- latch = new CountDownLatch(4);
- testTraceWriter.start();
-
- // create a simple metrics record
- long traceid = 12345;
- List spans = new ArrayList();
-
- Span span =
- createNewSpan(traceid, Span.ROOT_SPAN_ID, 7777, "root", 10, 30,
- "root process", "root-span tag");
- spans.add(span);
-
- // then create a child record
- span =
- createNewSpan(traceid, 7777, 6666, "c1", 11, 15, "c1 process",
- "first child");
- spans.add(span);
-
- // create a different child
- span =
- createNewSpan(traceid, 7777, 5555, "c2", 11, 18, "c2 process",
- "second child");
- spans.add(span);
-
- // create a child of the second child
- span =
- createNewSpan(traceid, 5555, 4444, "c3", 12, 16, "c3 process",
- "third child");
- spans.add(span);
-
- for(Span span1 : spans)
- Tracer.getInstance().deliver(span1);
-
- assertTrue("Updates not written in table", latch.await(100, TimeUnit.SECONDS));
-
- // start a reader
- validateTraces(spans, conn, traceid, tracingTableName);
- }
-
- private void validateTraces(List spans, Connection conn, long traceid, String tableName)
- throws Exception {
- TraceReader reader = new TraceReader(conn, tableName);
- Collection traces = reader.readAll(1);
- assertEquals("Got an unexpected number of traces!", 1, traces.size());
- // make sure the trace matches what we wrote
- TraceHolder trace = traces.iterator().next();
- assertEquals("Got an unexpected traceid", traceid, trace.traceid);
- assertEquals("Got an unexpected number of spans", spans.size(), trace.spans.size());
-
- validateTrace(spans, trace);
- }
-
- /**
- * @param spans
- * @param trace
- */
- private void validateTrace(List spans, TraceHolder trace) {
- // drop each span into a sorted list so we get the expected ordering
- Iterator spanIter = trace.spans.iterator();
- for (Span span : spans) {
- SpanInfo spanInfo = spanIter.next();
- LOGGER.info("Checking span:\n" + spanInfo);
-
- long parentId = span.getParentId();
- if(parentId == Span.ROOT_SPAN_ID) {
- assertNull("Got a parent, but it was a root span!", spanInfo.parent);
- } else {
- assertEquals("Got an unexpected parent span id", parentId, spanInfo.parent.id);
- }
-
- assertEquals("Got an unexpected start time", span.getStartTimeMillis(), spanInfo.start);
- assertEquals("Got an unexpected end time", span.getStopTimeMillis(), spanInfo.end);
-
- int annotationCount = 0;
- for(Map.Entry entry : span.getKVAnnotations().entrySet()) {
- int count = annotationCount++;
- assertEquals("Didn't get expected annotation", count + " - " + Bytes.toString(entry.getValue()),
- spanInfo.annotations.get(count));
- }
- assertEquals("Didn't get expected number of annotations", annotationCount,
- spanInfo.annotationCount);
- }
- }
-
- private void assertAnnotationPresent(final String annotationKey, final String annotationValue, Connection conn) throws Exception {
- boolean tracingComplete = checkStoredTraces(conn, new TraceChecker(){
- @Override
- public boolean foundTrace(TraceHolder currentTrace) {
- return currentTrace.toString().contains(annotationKey + " - " + annotationValue);
- }
- });
-
- assertTrue("Didn't find the custom annotation in the tracing", tracingComplete);
- }
-
- private boolean checkStoredTraces(Connection conn, TraceChecker checker) throws Exception {
- TraceReader reader = new TraceReader(conn, tracingTableName);
- int retries = 0;
- boolean found = false;
- outer: while (retries < MAX_RETRIES) {
- Collection traces = reader.readAll(100);
- for (TraceHolder trace : traces) {
- LOGGER.info("Got trace: " + trace);
- found = checker.foundTrace(trace);
- if (found) {
- break outer;
- }
- for (SpanInfo span : trace.spans) {
- found = checker.foundTrace(trace, span);
- if (found) {
- break outer;
- }
- }
- }
- LOGGER.info("====== Waiting for tracing updates to be propagated ========");
- Thread.sleep(1000);
- retries++;
- }
- return found;
- }
-
- private abstract class TraceChecker {
- public boolean foundTrace(TraceHolder currentTrace) {
- return false;
- }
-
- public boolean foundTrace(TraceHolder currentTrace, SpanInfo currentSpan) {
- return false;
- }
- }
+//
+// private static final Logger LOGGER = LoggerFactory.getLogger(PhoenixTracingEndToEndIT.class);
+// private static final int MAX_RETRIES = 10;
+// private String enabledForLoggingTable;
+// private String enableForLoggingIndex;
+//
+// @Before
+// public void setupMetrics() throws Exception {
+// enabledForLoggingTable = "ENABLED_FOR_LOGGING_" + generateUniqueName();
+// enableForLoggingIndex = "ENABALED_FOR_LOGGING_INDEX_" + generateUniqueName();
+// }
+//
+// /**
+// * Simple test that we can correctly write spans to the phoenix table
+// * @throws Exception on failure
+// */
+// @Test
+// public void testWriteSpans() throws Exception {
+//
+// LOGGER.info("testWriteSpans TableName: " + tracingTableName);
+// // watch our sink so we know when commits happen
+// latch = new CountDownLatch(1);
+//
+// testTraceWriter.start();
+//
+// // write some spans
+// TraceScope trace = Trace.startSpan("Start write test", Sampler.ALWAYS);
+// Span span = trace.getSpan();
+//
+// // add a child with some annotations
+// Span child = span.child("child 1");
+// child.addTimelineAnnotation("timeline annotation");
+// TracingUtils.addAnnotation(child, "test annotation", 10);
+// child.stop();
+//
+// // sleep a little bit to get some time difference
+// Thread.sleep(100);
+//
+// trace.close();
+//
+// // pass the trace on
+// Tracer.getInstance().deliver(span);
+//
+// // wait for the tracer to actually do the write
+// assertTrue("Sink not flushed. commit() not called on the connection", latch.await(60, TimeUnit.SECONDS));
+//
+// // look for the writes to make sure they were made
+// Connection conn = getConnectionWithoutTracing();
+// checkStoredTraces(conn, new TraceChecker() {
+// @Override
+// public boolean foundTrace(TraceHolder trace, SpanInfo info) {
+// if (info.description.equals("child 1")) {
+// assertEquals("Not all annotations present", 1, info.annotationCount);
+// assertEquals("Not all tags present", 1, info.tagCount);
+// boolean found = false;
+// for (String annotation : info.annotations) {
+// if (annotation.startsWith("test annotation")) {
+// found = true;
+// }
+// }
+// assertTrue("Missing the annotations in span: " + info, found);
+// found = false;
+// for (String tag : info.tags) {
+// if (tag.endsWith("timeline annotation")) {
+// found = true;
+// }
+// }
+// assertTrue("Missing the tags in span: " + info, found);
+// return true;
+// }
+// return false;
+// }
+// });
+// }
+//
+// /**
+// * Test that span will actually go into the this sink and be written on both side of the wire,
+// * through the indexing code.
+// * @throws Exception
+// */
+// @Test
+// public void testClientServerIndexingTracing() throws Exception {
+//
+// LOGGER.info("testClientServerIndexingTracing TableName: " + tracingTableName);
+// // one call for client side, one call for server side
+// latch = new CountDownLatch(2);
+// testTraceWriter.start();
+//
+// // separate connection so we don't create extra traces
+// Connection conn = getConnectionWithoutTracing();
+// createTestTable(conn, true);
+//
+// // trace the requests we send
+// Connection traceable = getTracingConnection();
+// LOGGER.debug("Doing dummy the writes to the tracked table");
+// String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
+// PreparedStatement stmt = traceable.prepareStatement(insert);
+// stmt.setString(1, "key1");
+// stmt.setLong(2, 1);
+// // this first trace just does a simple open/close of the span. Its not doing anything
+// // terribly interesting because we aren't auto-committing on the connection, so it just
+// // updates the mutation state and returns.
+// stmt.execute();
+// stmt.setString(1, "key2");
+// stmt.setLong(2, 2);
+// stmt.execute();
+// traceable.commit();
+//
+// // wait for the latch to countdown, as the metrics system is time-based
+// LOGGER.debug("Waiting for latch to complete!");
+// latch.await(200, TimeUnit.SECONDS);// should be way more than GC pauses
+//
+// // read the traces back out
+//
+// /* Expected:
+// * 1. Single element trace - for first PreparedStatement#execute span
+// * 2. Two element trace for second PreparedStatement#execute span
+// * a. execute call
+// * b. metadata lookup*
+// * 3. Commit trace.
+// * a. Committing to tables
+// * i. Committing to single table
+// * ii. hbase batch write*
+// * i.I. span on server
+// * i.II. building index updates
+// * i.III. waiting for latch
+// * where '*' is a generically named thread (e.g phoenix-1-thread-X)
+// */
+// boolean indexingCompleted = checkStoredTraces(conn, new TraceChecker() {
+// @Override
+// public boolean foundTrace(TraceHolder trace, SpanInfo span) {
+// String traceInfo = trace.toString();
+// // skip logging traces that are just traces about tracing
+// if (traceInfo.contains(tracingTableName)) {
+// return false;
+// }
+// return traceInfo.contains("Completing index");
+// }
+// });
+//
+// assertTrue("Never found indexing updates", indexingCompleted);
+// }
+//
+// private void createTestTable(Connection conn, boolean withIndex) throws SQLException {
+// // create a dummy table
+// String ddl =
+// "create table if not exists " + enabledForLoggingTable + "(" + "k varchar not null, " + "c1 bigint"
+// + " CONSTRAINT pk PRIMARY KEY (k))";
+// conn.createStatement().execute(ddl);
+//
+// // early exit if we don't need to create an index
+// if (!withIndex) {
+// return;
+// }
+// // create an index on the table - we know indexing has some basic tracing
+// ddl = "CREATE INDEX IF NOT EXISTS " + enableForLoggingIndex + " on " + enabledForLoggingTable + " (c1)";
+// conn.createStatement().execute(ddl);
+// }
+//
+// @Test
+// public void testScanTracing() throws Exception {
+//
+// LOGGER.info("testScanTracing TableName: " + tracingTableName);
+//
+// // separate connections to minimize amount of traces that are generated
+// Connection traceable = getTracingConnection();
+// Connection conn = getConnectionWithoutTracing();
+//
+// // one call for client side, one call for server side
+// latch = new CountDownLatch(2);
+// testTraceWriter.start();
+//
+// // create a dummy table
+// createTestTable(conn, false);
+//
+// // update the table, but don't trace these, to simplify the traces we read
+// LOGGER.debug("Doing dummy the writes to the tracked table");
+// String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
+// PreparedStatement stmt = conn.prepareStatement(insert);
+// stmt.setString(1, "key1");
+// stmt.setLong(2, 1);
+// stmt.execute();
+// conn.commit();
+// conn.rollback();
+//
+// // setup for next set of updates
+// stmt.setString(1, "key2");
+// stmt.setLong(2, 2);
+// stmt.execute();
+// conn.commit();
+// conn.rollback();
+//
+// // do a scan of the table
+// String read = "SELECT * FROM " + enabledForLoggingTable;
+// ResultSet results = traceable.createStatement().executeQuery(read);
+// assertTrue("Didn't get first result", results.next());
+// assertTrue("Didn't get second result", results.next());
+// results.close();
+//
+// assertTrue("Get expected updates to trace table", latch.await(200, TimeUnit.SECONDS));
+// // don't trace reads either
+// boolean tracingComplete = checkStoredTraces(conn, new TraceChecker(){
+//
+// @Override
+// public boolean foundTrace(TraceHolder currentTrace) {
+// String traceInfo = currentTrace.toString();
+// return traceInfo.contains("Parallel scanner");
+// }
+// });
+// assertTrue("Didn't find the parallel scanner in the tracing", tracingComplete);
+// }
+//
+// @Test
+// public void testScanTracingOnServer() throws Exception {
+//
+// LOGGER.info("testScanTracingOnServer TableName: " + tracingTableName);
+//
+// // separate connections to minimize amount of traces that are generated
+// Connection traceable = getTracingConnection();
+// Connection conn = getConnectionWithoutTracing();
+//
+// // one call for client side, one call for server side
+// latch = new CountDownLatch(5);
+// testTraceWriter.start();
+//
+// // create a dummy table
+// createTestTable(conn, false);
+//
+// // update the table, but don't trace these, to simplify the traces we read
+// LOGGER.debug("Doing dummy the writes to the tracked table");
+// String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
+// PreparedStatement stmt = conn.prepareStatement(insert);
+// stmt.setString(1, "key1");
+// stmt.setLong(2, 1);
+// stmt.execute();
+// conn.commit();
+//
+// // setup for next set of updates
+// stmt.setString(1, "key2");
+// stmt.setLong(2, 2);
+// stmt.execute();
+// conn.commit();
+//
+// // do a scan of the table
+// String read = "SELECT COUNT(*) FROM " + enabledForLoggingTable;
+// ResultSet results = traceable.createStatement().executeQuery(read);
+// assertTrue("Didn't get count result", results.next());
+// // make sure we got the expected count
+// assertEquals("Didn't get the expected number of row", 2, results.getInt(1));
+// results.close();
+//
+// assertTrue("Didn't get expected updates to trace table", latch.await(60, TimeUnit.SECONDS));
+//
+// // don't trace reads either
+// boolean found = checkStoredTraces(conn, new TraceChecker() {
+// @Override
+// public boolean foundTrace(TraceHolder trace) {
+// String traceInfo = trace.toString();
+// return traceInfo.contains(BaseScannerRegionObserver.SCANNER_OPENED_TRACE_INFO);
+// }
+// });
+// assertTrue("Didn't find the parallel scanner in the tracing", found);
+// }
+//
+// @Test
+// public void testCustomAnnotationTracing() throws Exception {
+//
+// LOGGER.info("testCustomAnnotationTracing TableName: " + tracingTableName);
+//
+// final String customAnnotationKey = "myannot";
+// final String customAnnotationValue = "a1";
+// final String tenantId = "tenant1";
+// // separate connections to minimize amount of traces that are generated
+// Connection traceable = getTracingConnection(ImmutableMap.of(customAnnotationKey, customAnnotationValue), tenantId);
+// Connection conn = getConnectionWithoutTracing();
+//
+// // one call for client side, one call for server side
+// latch = new CountDownLatch(2);
+// testTraceWriter.start();
+//
+// // create a dummy table
+// createTestTable(conn, false);
+//
+// // update the table, but don't trace these, to simplify the traces we read
+// LOGGER.debug("Doing dummy the writes to the tracked table");
+// String insert = "UPSERT INTO " + enabledForLoggingTable + " VALUES (?, ?)";
+// PreparedStatement stmt = conn.prepareStatement(insert);
+// stmt.setString(1, "key1");
+// stmt.setLong(2, 1);
+// stmt.execute();
+// conn.commit();
+// conn.rollback();
+//
+// // setup for next set of updates
+// stmt.setString(1, "key2");
+// stmt.setLong(2, 2);
+// stmt.execute();
+// conn.commit();
+// conn.rollback();
+//
+// // do a scan of the table
+// String read = "SELECT * FROM " + enabledForLoggingTable;
+// ResultSet results = traceable.createStatement().executeQuery(read);
+// assertTrue("Didn't get first result", results.next());
+// assertTrue("Didn't get second result", results.next());
+// results.close();
+//
+// assertTrue("Get expected updates to trace table", latch.await(200, TimeUnit.SECONDS));
+//
+// assertAnnotationPresent(customAnnotationKey, customAnnotationValue, conn);
+// assertAnnotationPresent(TENANT_ID_ATTRIB, tenantId, conn);
+// // CurrentSCN is also added as an annotation. Not tested here because it screws up test setup.
+// }
+//
+// @Test
+// public void testTraceOnOrOff() throws Exception {
+// Connection conn1 = getConnectionWithoutTracing(); //DriverManager.getConnection(getUrl());
+// try{
+// Statement statement = conn1.createStatement();
+// ResultSet rs = statement.executeQuery("TRACE ON");
+// assertTrue(rs.next());
+// PhoenixConnection pconn = (PhoenixConnection) conn1;
+// long traceId = pconn.getTraceScope().getSpan().getTraceId();
+// assertEquals(traceId, rs.getLong(1));
+// assertEquals(traceId, rs.getLong("trace_id"));
+// assertFalse(rs.next());
+// assertEquals(Sampler.ALWAYS, pconn.getSampler());
+//
+// rs = statement.executeQuery("TRACE OFF");
+// assertTrue(rs.next());
+// assertEquals(traceId, rs.getLong(1));
+// assertEquals(traceId, rs.getLong("trace_id"));
+// assertFalse(rs.next());
+// assertEquals(Sampler.NEVER, pconn.getSampler());
+//
+// rs = statement.executeQuery("TRACE OFF");
+// assertFalse(rs.next());
+//
+// rs = statement.executeQuery("TRACE ON WITH SAMPLING 0.5");
+// rs.next();
+// assertTrue(((PhoenixConnection) conn1).getSampler() instanceof ProbabilitySampler);
+//
+// rs = statement.executeQuery("TRACE ON WITH SAMPLING 1.0");
+// assertTrue(rs.next());
+// traceId = pconn.getTraceScope().getSpan()
+// .getTraceId();
+// assertEquals(traceId, rs.getLong(1));
+// assertEquals(traceId, rs.getLong("trace_id"));
+// assertFalse(rs.next());
+// assertEquals(Sampler.ALWAYS, pconn.getSampler());
+//
+// rs = statement.executeQuery("TRACE ON WITH SAMPLING 0.5");
+// rs.next();
+// assertTrue(((PhoenixConnection) conn1).getSampler() instanceof ProbabilitySampler);
+//
+// rs = statement.executeQuery("TRACE ON WITH SAMPLING 0.0");
+// rs.next();
+// assertEquals(Sampler.NEVER, pconn.getSampler());
+//
+// rs = statement.executeQuery("TRACE OFF");
+// assertFalse(rs.next());
+//
+// } finally {
+// conn1.close();
+// }
+// }
+//
+// @Test
+// public void testSingleSpan() throws Exception {
+//
+// LOGGER.info("testSingleSpan TableName: " + tracingTableName);
+//
+// Properties props = new Properties(TEST_PROPERTIES);
+// Connection conn = DriverManager.getConnection(getUrl(), props);
+// latch = new CountDownLatch(1);
+// testTraceWriter.start();
+//
+// // create a simple metrics record
+// long traceid = 987654;
+// Span span = createNewSpan(traceid, Span.ROOT_SPAN_ID, 10, "root", 12, 13, "Some process", "test annotation for a span");
+//
+// Tracer.getInstance().deliver(span);
+// assertTrue("Updates not written in table", latch.await(60, TimeUnit.SECONDS));
+//
+// // start a reader
+// validateTraces(Collections.singletonList(span), conn, traceid, tracingTableName);
+// }
+//
+// /**
+// * Test multiple spans, within the same trace. Some spans are independent of the parent span,
+// * some are child spans
+// * @throws Exception on failure
+// */
+// @Test
+// public void testMultipleSpans() throws Exception {
+//
+// LOGGER.info("testMultipleSpans TableName: " + tracingTableName);
+//
+// Connection conn = getConnectionWithoutTracing();
+// latch = new CountDownLatch(4);
+// testTraceWriter.start();
+//
+// // create a simple metrics record
+// long traceid = 12345;
+// List spans = new ArrayList();
+//
+// Span span =
+// createNewSpan(traceid, Span.ROOT_SPAN_ID, 7777, "root", 10, 30,
+// "root process", "root-span tag");
+// spans.add(span);
+//
+// // then create a child record
+// span =
+// createNewSpan(traceid, 7777, 6666, "c1", 11, 15, "c1 process",
+// "first child");
+// spans.add(span);
+//
+// // create a different child
+// span =
+// createNewSpan(traceid, 7777, 5555, "c2", 11, 18, "c2 process",
+// "second child");
+// spans.add(span);
+//
+// // create a child of the second child
+// span =
+// createNewSpan(traceid, 5555, 4444, "c3", 12, 16, "c3 process",
+// "third child");
+// spans.add(span);
+//
+// for(Span span1 : spans)
+// Tracer.getInstance().deliver(span1);
+//
+// assertTrue("Updates not written in table", latch.await(100, TimeUnit.SECONDS));
+//
+// // start a reader
+// validateTraces(spans, conn, traceid, tracingTableName);
+// }
+//
+// private void validateTraces(List spans, Connection conn, long traceid, String tableName)
+// throws Exception {
+// TraceReader reader = new TraceReader(conn, tableName);
+// Collection traces = reader.readAll(1);
+// assertEquals("Got an unexpected number of traces!", 1, traces.size());
+// // make sure the trace matches what we wrote
+// TraceHolder trace = traces.iterator().next();
+// assertEquals("Got an unexpected traceid", traceid, trace.traceid);
+// assertEquals("Got an unexpected number of spans", spans.size(), trace.spans.size());
+//
+// validateTrace(spans, trace);
+// }
+//
+// /**
+// * @param spans
+// * @param trace
+// */
+// private void validateTrace(List spans, TraceHolder trace) {
+// // drop each span into a sorted list so we get the expected ordering
+// Iterator spanIter = trace.spans.iterator();
+// for (Span span : spans) {
+// SpanInfo spanInfo = spanIter.next();
+// LOGGER.info("Checking span:\n" + spanInfo);
+//
+// long parentId = span.getParentId();
+// if(parentId == Span.ROOT_SPAN_ID) {
+// assertNull("Got a parent, but it was a root span!", spanInfo.parent);
+// } else {
+// assertEquals("Got an unexpected parent span id", parentId, spanInfo.parent.id);
+// }
+//
+// assertEquals("Got an unexpected start time", span.getStartTimeMillis(), spanInfo.start);
+// assertEquals("Got an unexpected end time", span.getStopTimeMillis(), spanInfo.end);
+//
+// int annotationCount = 0;
+// for(Map.Entry entry : span.getKVAnnotations().entrySet()) {
+// int count = annotationCount++;
+// assertEquals("Didn't get expected annotation", count + " - " + Bytes.toString(entry.getValue()),
+// spanInfo.annotations.get(count));
+// }
+// assertEquals("Didn't get expected number of annotations", annotationCount,
+// spanInfo.annotationCount);
+// }
+// }
+//
+// private void assertAnnotationPresent(final String annotationKey, final String annotationValue, Connection conn) throws Exception {
+// boolean tracingComplete = checkStoredTraces(conn, new TraceChecker(){
+// @Override
+// public boolean foundTrace(TraceHolder currentTrace) {
+// return currentTrace.toString().contains(annotationKey + " - " + annotationValue);
+// }
+// });
+//
+// assertTrue("Didn't find the custom annotation in the tracing", tracingComplete);
+// }
+//
+// private boolean checkStoredTraces(Connection conn, TraceChecker checker) throws Exception {
+// TraceReader reader = new TraceReader(conn, tracingTableName);
+// int retries = 0;
+// boolean found = false;
+// outer: while (retries < MAX_RETRIES) {
+// Collection traces = reader.readAll(100);
+// for (TraceHolder trace : traces) {
+// LOGGER.info("Got trace: " + trace);
+// found = checker.foundTrace(trace);
+// if (found) {
+// break outer;
+// }
+// for (SpanInfo span : trace.spans) {
+// found = checker.foundTrace(trace, span);
+// if (found) {
+// break outer;
+// }
+// }
+// }
+// LOGGER.info("====== Waiting for tracing updates to be propagated ========");
+// Thread.sleep(1000);
+// retries++;
+// }
+// return found;
+// }
+//
+// private abstract class TraceChecker {
+// public boolean foundTrace(TraceHolder currentTrace) {
+// return false;
+// }
+//
+// public boolean foundTrace(TraceHolder currentTrace, SpanInfo currentSpan) {
+// return false;
+// }
+// }
}
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index 5cb73379bb2..767510872fa 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -212,7 +212,7 @@ import org.apache.phoenix.schema.types.PUnsignedTime;
import org.apache.phoenix.schema.types.PUnsignedTimestamp;
import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.parse.LikeParseNode.LikeType;
-import org.apache.phoenix.trace.util.Tracing;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.parse.AddJarsStatement;
import org.apache.phoenix.parse.ExplainType;
}
@@ -663,7 +663,7 @@ alter_index_node returns [AlterIndexStatement ret]
// Parse a trace statement.
trace_node returns [TraceStatement ret]
: TRACE ((flag = ON ( WITH SAMPLING s = sampling_rate)?) | flag = OFF)
- {ret = factory.trace(Tracing.isTraceOn(flag.getText()), s == null ? Tracing.isTraceOn(flag.getText()) ? 1.0 : 0.0 : (((BigDecimal)s.getValue())).doubleValue());}
+ {ret = factory.trace(TraceUtil.isTraceOn(flag.getText()), s == null ? TraceUtil.isTraceOn(flag.getText()) ? 1.0 : 0.0 : (((BigDecimal)s.getValue())).doubleValue());}
;
// Parse a create function statement.
diff --git a/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/IndexRpcController.java b/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/IndexRpcController.java
index b8976ce222c..da056e1e4b5 100644
--- a/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/IndexRpcController.java
+++ b/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/IndexRpcController.java
@@ -22,8 +22,6 @@
import org.apache.hadoop.hbase.ipc.DelegatingHBaseRpcController;
import org.apache.hadoop.hbase.ipc.HBaseRpcController;
import org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory;
-import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.query.QueryServicesOptions;
import com.google.protobuf.RpcController;
@@ -34,18 +32,15 @@
class IndexRpcController extends DelegatingHBaseRpcController {
private final int priority;
- private final String tracingTableName;
public IndexRpcController(HBaseRpcController delegate, Configuration conf) {
super(delegate);
this.priority = PhoenixRpcSchedulerFactory.getIndexPriority(conf);
- this.tracingTableName = conf.get(QueryServices.TRACING_STATS_TABLE_NAME_ATTRIB,
- QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
}
@Override
public void setPriority(final TableName tn) {
- if (!tn.isSystemTable() && !tn.getNameAsString().equals(tracingTableName)) {
+ if (!tn.isSystemTable()) {
setPriority(this.priority);
}
else {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
index d8238c05be1..daaf84798c1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
@@ -29,10 +29,7 @@
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.htrace.Sampler;
-import org.apache.htrace.TraceScope;
-import org.apache.phoenix.compile.ExplainPlanAttributes
- .ExplainPlanAttributesBuilder;
+import org.apache.phoenix.compile.ExplainPlanAttributes.ExplainPlanAttributesBuilder;
import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
import org.apache.phoenix.execute.visitor.QueryPlanVisitor;
@@ -62,8 +59,7 @@
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.schema.tuple.ResultTuple;
import org.apache.phoenix.schema.tuple.Tuple;
-import org.apache.phoenix.schema.types.PLong;
-import org.apache.phoenix.trace.util.Tracing;
+import org.apache.phoenix.schema.types.PChar;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.EnvironmentEdgeManager;
import org.apache.phoenix.util.PhoenixKeyValueUtil;
@@ -76,13 +72,16 @@ public class TraceQueryPlan implements QueryPlan {
private StatementContext context = null;
private boolean first = true;
+ // 8 bytes represented by 16 hex characters
+ private static int SPAN_ID_CHAR_LENGTH=16;
+
private static final RowProjector TRACE_PROJECTOR;
static {
List projectedColumns = new ArrayList();
PName colName = PNameFactory.newName(MetricInfo.TRACE.columnName);
PColumn column =
new PColumnImpl(PNameFactory.newName(MetricInfo.TRACE.columnName), null,
- PLong.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null,
+ PChar.INSTANCE, SPAN_ID_CHAR_LENGTH, null, false, 0, SortOrder.getDefault(), 0, null,
false, null, false, false, colName.getBytes(), HConstants.LATEST_TIMESTAMP);
List columns = new ArrayList();
columns.add(column);
@@ -90,7 +89,7 @@ public class TraceQueryPlan implements QueryPlan {
new RowKeyColumnExpression(column, new RowKeyValueAccessor(columns, 0));
projectedColumns.add(new ExpressionProjector(MetricInfo.TRACE.columnName, MetricInfo.TRACE.columnName, "", expression,
true));
- int estimatedByteSize = SizedUtil.KEY_VALUE_SIZE + PLong.INSTANCE.getByteSize();
+ int estimatedByteSize = SizedUtil.KEY_VALUE_SIZE + SPAN_ID_CHAR_LENGTH;
TRACE_PROJECTOR = new RowProjector(projectedColumns, estimatedByteSize, false);
}
@@ -128,7 +127,7 @@ public ResultIterator iterator(ParallelScanGrouper scanGrouper, Scan scan) throw
@Override
public ResultIterator iterator(ParallelScanGrouper scanGrouper) throws SQLException {
final PhoenixConnection conn = stmt.getConnection();
- if (conn.getTraceScope() == null && !traceStatement.isTraceOn()) {
+ if (conn.getManualTraceSpanId() == null && !traceStatement.isTraceOn()) {
return ResultIterator.EMPTY_ITERATOR;
}
return new TraceQueryResultIterator(conn);
@@ -136,7 +135,7 @@ public ResultIterator iterator(ParallelScanGrouper scanGrouper) throws SQLExcept
@Override
public long getEstimatedSize() {
- return PLong.INSTANCE.getByteSize();
+ return SPAN_ID_CHAR_LENGTH;
}
@Override
@@ -258,51 +257,36 @@ public void close() throws SQLException {
@Override
public Tuple next() throws SQLException {
- if(!first) return null;
- TraceScope traceScope = conn.getTraceScope();
+ if (!first) {
+ return null;
+ }
if (traceStatement.isTraceOn()) {
- conn.setSampler(Tracing.getConfiguredSampler(traceStatement));
- if (conn.getSampler() == Sampler.NEVER) {
- closeTraceScope(conn);
- }
- if (traceScope == null && !conn.getSampler().equals(Sampler.NEVER)) {
- traceScope = Tracing.startNewSpan(conn, "Enabling trace");
- if (traceScope.getSpan() != null) {
- conn.setTraceScope(traceScope);
- } else {
- closeTraceScope(conn);
- }
- }
+ conn.startManualTraceSpan();
} else {
- closeTraceScope(conn);
- conn.setSampler(Sampler.NEVER);
+ conn.endManualTraceSpan();
}
- if (traceScope == null || traceScope.getSpan() == null) return null;
first = false;
- ImmutableBytesWritable ptr = new ImmutableBytesWritable();
- ParseNodeFactory factory = new ParseNodeFactory();
- LiteralParseNode literal =
- factory.literal(traceScope.getSpan().getTraceId());
- LiteralExpression expression =
- LiteralExpression.newConstant(literal.getValue(), PLong.INSTANCE,
- Determinism.ALWAYS);
- expression.evaluate(null, ptr);
- byte[] rowKey = ByteUtil.copyKeyBytesIfNecessary(ptr);
- Cell cell =
- PhoenixKeyValueUtil
- .newKeyValue(rowKey, HConstants.EMPTY_BYTE_ARRAY,
- HConstants.EMPTY_BYTE_ARRAY,
- EnvironmentEdgeManager.currentTimeMillis(),
- HConstants.EMPTY_BYTE_ARRAY);
- List cells = new ArrayList(1);
- cells.add(cell);
- return new ResultTuple(Result.create(cells));
- }
-
- private void closeTraceScope(final PhoenixConnection conn) {
- if(conn.getTraceScope()!=null) {
- conn.getTraceScope().close();
- conn.setTraceScope(null);
+ String traceSpanId = conn.getManualTraceSpanId();
+ if (traceSpanId != null) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ ParseNodeFactory factory = new ParseNodeFactory();
+ LiteralParseNode literal = factory.literal(traceSpanId);
+ LiteralExpression expression =
+ LiteralExpression.newConstant(literal.getValue(), PChar.INSTANCE,
+ Determinism.ALWAYS);
+ expression.evaluate(null, ptr);
+ byte[] rowKey = ByteUtil.copyKeyBytesIfNecessary(ptr);
+ Cell cell =
+ PhoenixKeyValueUtil
+ .newKeyValue(rowKey, HConstants.EMPTY_BYTE_ARRAY,
+ HConstants.EMPTY_BYTE_ARRAY,
+ EnvironmentEdgeManager.currentTimeMillis(),
+ HConstants.EMPTY_BYTE_ARRAY);
+ List cells = new ArrayList(1);
+ cells.add(cell);
+ return new ResultTuple(Result.create(cells));
+ } else {
+ return null;
}
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
index 7493acceacc..60c67cba0f2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
@@ -17,6 +17,8 @@
*/
package org.apache.phoenix.coprocessor;
+import static org.apache.phoenix.util.ScanUtil.getPageSizeMsForFilter;
+
import java.io.IOException;
import java.util.List;
@@ -46,8 +48,6 @@
import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.apache.htrace.Span;
-import org.apache.htrace.Trace;
import org.apache.phoenix.execute.TupleProjector;
import org.apache.phoenix.filter.PagingFilter;
import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
@@ -58,10 +58,12 @@
import org.apache.phoenix.query.QueryServicesOptions;
import org.apache.phoenix.schema.StaleRegionBoundaryCacheException;
import org.apache.phoenix.schema.types.PUnsignedTinyint;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.util.ScanUtil;
import org.apache.phoenix.util.ServerUtil;
-import static org.apache.phoenix.util.ScanUtil.getPageSizeMsForFilter;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Scope;
abstract public class BaseScannerRegionObserver implements RegionObserver {
@@ -300,9 +302,10 @@ private void overrideDelegate() throws IOException {
// and region servers to crash. See https://issues.apache.org/jira/browse/PHOENIX-1596
// TraceScope can't be used here because closing the scope will end up calling
// currentSpan.stop() and that should happen only when we are closing the scanner.
- final Span savedSpan = Trace.currentSpan();
- final Span child = Trace.startSpan(SCANNER_OPENED_TRACE_INFO, savedSpan).getSpan();
- try {
+ //FIXME I don't think the above is true for OpenTelemetry.
+ //Just use the standard pattern, and see if it works.
+ Span span = TraceUtil.createServerSideSpan(SCANNER_OPENED_TRACE_INFO);
+ try (Scope scope = span.makeCurrent();){
RegionScanner scanner = doPostScannerOpen(c, scan, delegate);
scanner = new DelegateRegionScanner(scanner) {
// This isn't very obvious but close() could be called in a thread
@@ -312,9 +315,7 @@ public void close() throws IOException {
try {
delegate.close();
} finally {
- if (child != null) {
- child.stop();
- }
+ span.end();
}
}
};
@@ -322,16 +323,10 @@ public void close() throws IOException {
wasOverriden = true;
success = true;
} catch (Throwable t) {
+ TraceUtil.setError(span, t);
ServerUtil.throwIOException(c.getEnvironment().getRegionInfo().getRegionNameAsString(), t);
- } finally {
- try {
- if (!success && child != null) {
- child.stop();
- }
- } finally {
- Trace.continueSpan(savedSpan);
- }
}
+ // span is closed in scanner.close()
}
@Override
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 46055544099..fb2ef3fcc35 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -244,7 +244,6 @@
import org.apache.phoenix.schema.types.PTinyint;
import org.apache.phoenix.schema.types.PVarbinary;
import org.apache.phoenix.schema.types.PVarchar;
-import org.apache.phoenix.trace.util.Tracing;
import org.apache.phoenix.transaction.TransactionFactory;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.EncodedColumnsUtil;
@@ -631,8 +630,6 @@ public void start(CoprocessorEnvironment env) throws IOException {
QueryServicesOptions.DEFAULT_ALLOW_SPLITTABLE_SYSTEM_CATALOG_ROLLBACK);
LOGGER.info("Starting Tracing-Metrics Systems");
- // Start the phoenix trace collection
- Tracing.addTraceMetricsSource();
Metrics.ensureConfigured();
metricsSource = MetricsMetadataSourceFactory.getMetadataMetricsSource();
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
index ded8f17c67d..d28890bb6d6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
@@ -34,7 +34,6 @@
import org.apache.hadoop.hbase.io.TimeRange;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.WritableUtils;
-import org.apache.htrace.TraceScope;
import org.apache.phoenix.cache.ServerCacheClient.ServerCache;
import org.apache.phoenix.compile.ExplainPlan;
import org.apache.phoenix.compile.ExplainPlanAttributes;
@@ -47,10 +46,8 @@
import org.apache.phoenix.compile.RowProjector;
import org.apache.phoenix.compile.ScanRanges;
import org.apache.phoenix.compile.StatementContext;
-import org.apache.phoenix.compile.WhereCompiler;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
import org.apache.phoenix.coprocessor.MetaDataProtocol;
-import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.ProjectedColumnExpression;
import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
import org.apache.phoenix.index.IndexMaintainer;
@@ -76,11 +73,9 @@
import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.TableRef;
-import org.apache.phoenix.thirdparty.com.google.common.base.Optional;
import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableSet;
import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
import org.apache.phoenix.trace.TracingIterator;
-import org.apache.phoenix.trace.util.Tracing;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.LogUtil;
@@ -90,7 +85,6 @@
import org.slf4j.LoggerFactory;
-
/**
*
* Query plan that has no child plans
@@ -357,19 +351,15 @@ public final ResultIterator iterator(final Map ca
"Scan on table " + context.getCurrentTable().getTable().getName() + " ready for iteration: " + scan, connection));
}
+
ResultIterator iterator = newIterator(scanGrouper, scan, caches);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(LogUtil.addCustomAnnotations(
"Iterator for table " + context.getCurrentTable().getTable().getName() + " ready: " + iterator, connection));
}
- // wrap the iterator so we start/end tracing as we expect
- if (Tracing.isTracing()) {
- TraceScope scope = Tracing.startNewSpan(context.getConnection(),
- "Creating basic query for " + getPlanSteps(iterator));
- if (scope.getSpan() != null) return new TracingIterator(scope, iterator);
- }
- return iterator;
+ return new TracingIterator(iterator);
+
}
private void serializeIndexMaintainerIntoScan(Scan scan, PTable dataTable) throws SQLException {
@@ -521,12 +511,6 @@ public ExplainPlan getExplainPlan() throws SQLException {
return explainPlan;
}
- private List getPlanSteps(ResultIterator iterator) {
- List planSteps = Lists.newArrayListWithExpectedSize(5);
- iterator.explain(planSteps);
- return planSteps;
- }
-
private Pair, ExplainPlanAttributes> getPlanStepsV2(
ResultIterator iterator) {
List planSteps = Lists.newArrayListWithExpectedSize(5);
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
index 1cf23d7e0f4..a4e9f1bf821 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
@@ -60,8 +60,6 @@
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
-import org.apache.htrace.Span;
-import org.apache.htrace.TraceScope;
import org.apache.phoenix.cache.ServerCacheClient.ServerCache;
import org.apache.phoenix.compile.MutationPlan;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
@@ -107,7 +105,7 @@
import org.apache.phoenix.schema.types.PLong;
import org.apache.phoenix.schema.types.PTimestamp;
import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
-import org.apache.phoenix.trace.util.Tracing;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.transaction.PhoenixTransactionContext;
import org.apache.phoenix.transaction.PhoenixTransactionContext.PhoenixVisibilityLevel;
import org.apache.phoenix.transaction.TransactionFactory;
@@ -126,6 +124,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
import org.apache.phoenix.thirdparty.com.google.common.base.Preconditions;
import org.apache.phoenix.thirdparty.com.google.common.base.Predicate;
import org.apache.phoenix.thirdparty.com.google.common.collect.Iterators;
@@ -1212,8 +1214,8 @@ private void sendBatch(Map commitBatch, long[]
Map> physicalTableMutationMap = Maps.newLinkedHashMap();
// add tracing for this operation
- try (TraceScope trace = Tracing.startNewSpan(connection, "Committing mutations to tables")) {
- Span span = trace.getSpan();
+ Span span = TraceUtil.createSpan(connection, "Committing mutations to tables");
+ try (Scope ignored = span.makeCurrent()) {
ImmutableBytesWritable indexMetaDataPtr = new ImmutableBytesWritable();
for (Map.Entry entry : commitBatch.entrySet()) {
// at this point we are going through mutations for each table
@@ -1277,23 +1279,29 @@ private void sendBatch(Map commitBatch, long[]
verifiedOrDeletedIndexMutations);
// Phase 1: Send index mutations with the empty column value = "unverified"
- sendMutations(unverifiedIndexMutations.entrySet().iterator(), span, indexMetaDataPtr, false);
+ sendMutations(unverifiedIndexMutations.entrySet().iterator(), indexMetaDataPtr, false);
// Phase 2: Send data table and other indexes
- sendMutations(physicalTableMutationMap.entrySet().iterator(), span, indexMetaDataPtr, false);
+ sendMutations(physicalTableMutationMap.entrySet().iterator(), indexMetaDataPtr, false);
// Phase 3: Send put index mutations with the empty column value = "verified" and/or delete index mutations
try {
- sendMutations(verifiedOrDeletedIndexMutations.entrySet().iterator(), span, indexMetaDataPtr, true);
+ sendMutations(verifiedOrDeletedIndexMutations.entrySet().iterator(), indexMetaDataPtr, true);
} catch (SQLException ex) {
LOGGER.warn(
"Ignoring exception that happened during setting index verified value to verified=TRUE ",
ex);
}
+ span.setStatus(StatusCode.OK);
+ } catch (SQLException e) {
+ TraceUtil.setError(span, e);
+ throw e;
+ } finally {
+ span.end();
}
}
- private void sendMutations(Iterator>> mutationsIterator, Span span, ImmutableBytesWritable indexMetaDataPtr, boolean isVerifiedPhase)
+ private void sendMutations(Iterator>> mutationsIterator, ImmutableBytesWritable indexMetaDataPtr, boolean isVerifiedPhase)
throws SQLException {
while (mutationsIterator.hasNext()) {
Entry> pair = mutationsIterator.next();
@@ -1306,8 +1314,6 @@ private void sendMutations(Iterator>> mutationsI
// create a span per target table
// TODO maybe we can be smarter about the table name to string here?
- Span child = Tracing.child(span, "Writing mutation batch for table: " + Bytes.toString(htableName));
-
int retryCount = 0;
boolean shouldRetry = false;
long numMutations = 0;
@@ -1321,240 +1327,241 @@ private void sendMutations(Iterator>> mutationsI
boolean shouldRetryIndexedMutation = false;
IndexWriteException iwe = null;
do {
- TableRef origTableRef = tableInfo.getOrigTableRef();
- PTable table = origTableRef.getTable();
- table.getIndexMaintainers(indexMetaDataPtr, connection);
- final ServerCache cache = tableInfo.isDataTable() ?
- IndexMetaDataCacheClient.setMetaDataOnMutations(connection, table,
- mutationList, indexMetaDataPtr) : null;
- // If we haven't retried yet, retry for this case only, as it's possible that
- // a split will occur after we send the index metadata cache to all known
- // region servers.
- shouldRetry = cache != null;
- SQLException sqlE = null;
- Table hTable = connection.getQueryServices().getTable(htableName);
- List currentMutationBatch = null;
- boolean areAllBatchesSuccessful = false;
-
- try {
- if (table.isTransactional()) {
- // Track tables to which we've sent uncommitted data
- if (tableInfo.isDataTable()) {
- uncommittedPhysicalNames.add(table.getPhysicalName().getString());
- phoenixTransactionContext.markDMLFence(table);
+ Span span = TraceUtil.createSpan(connection, "Writing mutation batch for table: " + Bytes.toString(htableName));
+ try (Scope scope = span.makeCurrent()) {
+ TableRef origTableRef = tableInfo.getOrigTableRef();
+ PTable table = origTableRef.getTable();
+ table.getIndexMaintainers(indexMetaDataPtr, connection);
+ final ServerCache cache = tableInfo.isDataTable() ?
+ IndexMetaDataCacheClient.setMetaDataOnMutations(connection, table,
+ mutationList, indexMetaDataPtr) : null;
+ // If we haven't retried yet, retry for this case only, as it's possible that
+ // a split will occur after we send the index metadata cache to all known
+ // region servers.
+ shouldRetry = cache != null;
+ SQLException sqlE = null;
+ Table hTable = connection.getQueryServices().getTable(htableName);
+ List currentMutationBatch = null;
+ boolean areAllBatchesSuccessful = false;
+ try {
+ if (table.isTransactional()) {
+ // Track tables to which we've sent uncommitted data
+ if (tableInfo.isDataTable()) {
+ uncommittedPhysicalNames.add(table.getPhysicalName().getString());
+ phoenixTransactionContext.markDMLFence(table);
+ }
+ // Only pass true for last argument if the index is being written to on it's own (i.e. initial
+ // index population), not if it's being written to for normal maintenance due to writes to
+ // the data table. This case is different because the initial index population does not need
+ // to be done transactionally since the index is only made active after all writes have
+ // occurred successfully.
+ hTable = phoenixTransactionContext.getTransactionalTableWriter(connection, table, hTable, tableInfo.isDataTable() && table.getType() == PTableType.INDEX);
}
- // Only pass true for last argument if the index is being written to on it's own (i.e. initial
- // index population), not if it's being written to for normal maintenance due to writes to
- // the data table. This case is different because the initial index population does not need
- // to be done transactionally since the index is only made active after all writes have
- // occurred successfully.
- hTable = phoenixTransactionContext.getTransactionalTableWriter(connection, table, hTable, tableInfo.isDataTable() && table.getType() == PTableType.INDEX);
- }
- numMutations = mutationList.size();
- GLOBAL_MUTATION_BATCH_SIZE.update(numMutations);
- totalMutationBytesObject = calculateMutationSize(mutationList, true);
-
- child.addTimelineAnnotation("Attempt " + retryCount);
- Iterator> itrListMutation = mutationBatchList.iterator();
- while (itrListMutation.hasNext()) {
- final List mutationBatch = itrListMutation.next();
- currentMutationBatch = mutationBatch;
- if (shouldRetryIndexedMutation) {
- // if there was an index write failure, retry the mutation in a loop
- final Table finalHTable = hTable;
- final ImmutableBytesWritable finalindexMetaDataPtr =
- indexMetaDataPtr;
- final PTable finalPTable = table;
- PhoenixIndexFailurePolicy.doBatchWithRetries(new MutateCommand() {
- @Override
- public void doMutation() throws IOException {
- try {
- finalHTable.batch(mutationBatch, null);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new IOException(e);
- } catch (IOException e) {
- e = updateTableRegionCacheIfNecessary(e);
- throw e;
- }
- }
-
- @Override
- public List getMutationList() {
- return mutationBatch;
- }
-
- private IOException
- updateTableRegionCacheIfNecessary(IOException ioe) {
- SQLException sqlE =
- ServerUtil.parseLocalOrRemoteServerException(ioe);
- if (sqlE != null
- && sqlE.getErrorCode() == SQLExceptionCode.INDEX_METADATA_NOT_FOUND
- .getErrorCode()) {
+ numMutations = mutationList.size();
+ GLOBAL_MUTATION_BATCH_SIZE.update(numMutations);
+ totalMutationBytesObject = calculateMutationSize(mutationList, true);
+
+ span.addEvent("Attempt " + retryCount);
+ Iterator> itrListMutation = mutationBatchList.iterator();
+ while (itrListMutation.hasNext()) {
+ final List mutationBatch = itrListMutation.next();
+ currentMutationBatch = mutationBatch;
+ if (shouldRetryIndexedMutation) {
+ // if there was an index write failure, retry the mutation in a loop
+ final Table finalHTable = hTable;
+ final ImmutableBytesWritable finalindexMetaDataPtr =
+ indexMetaDataPtr;
+ final PTable finalPTable = table;
+ PhoenixIndexFailurePolicy.doBatchWithRetries(new MutateCommand() {
+ @Override
+ public void doMutation() throws IOException {
try {
- connection.getQueryServices().clearTableRegionCache(
- finalHTable.getName());
- IndexMetaDataCacheClient.setMetaDataOnMutations(
- connection, finalPTable, mutationBatch,
- finalindexMetaDataPtr);
- } catch (SQLException e) {
- return ServerUtil.createIOException(
- "Exception during updating index meta data cache",
- ioe);
+ finalHTable.batch(mutationBatch, null);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IOException(e);
+ } catch (IOException e) {
+ e = updateTableRegionCacheIfNecessary(e);
+ throw e;
}
}
- return ioe;
- }
- }, iwe, connection, connection.getQueryServices().getProps());
- shouldRetryIndexedMutation = false;
- } else {
- hTable.batch(mutationBatch, null);
- }
- // remove each batch from the list once it gets applied
- // so when failures happens for any batch we only start
- // from that batch only instead of doing duplicate reply of already
- // applied batches from entire list, also we can set
- // REPLAY_ONLY_INDEX_WRITES for first batch
- // only in case of 1121 SQLException
+
+ @Override
+ public List getMutationList() {
+ return mutationBatch;
+ }
+
+ private IOException
+ updateTableRegionCacheIfNecessary(IOException ioe) {
+ SQLException sqlE =
+ ServerUtil.parseLocalOrRemoteServerException(ioe);
+ if (sqlE != null
+ && sqlE.getErrorCode() == SQLExceptionCode.INDEX_METADATA_NOT_FOUND
+ .getErrorCode()) {
+ try {
+ connection.getQueryServices().clearTableRegionCache(
+ finalHTable.getName());
+ IndexMetaDataCacheClient.setMetaDataOnMutations(
+ connection, finalPTable, mutationBatch,
+ finalindexMetaDataPtr);
+ } catch (SQLException e) {
+ return ServerUtil.createIOException(
+ "Exception during updating index meta data cache",
+ ioe);
+ }
+ }
+ return ioe;
+ }
+ }, iwe, connection, connection.getQueryServices().getProps());
+ shouldRetryIndexedMutation = false;
+ } else {
+ hTable.batch(mutationBatch, null);
+ }
+ // remove each batch from the list once it gets applied
+ // so when failures happens for any batch we only start
+ // from that batch only instead of doing duplicate reply of already
+ // applied batches from entire list, also we can set
+ // REPLAY_ONLY_INDEX_WRITES for first batch
+ // only in case of 1121 SQLException
itrListMutation.remove();
- batchCount++;
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Sent batch of " + mutationBatch.size() + " for "
- + Bytes.toString(htableName));
- }
- child.stop();
- child.stop();
- shouldRetry = false;
- numFailedMutations = 0;
-
- // Remove batches as we process them
- removeMutations(this.mutationsMap, origTableRef);
- if (tableInfo.isDataTable()) {
- numRows -= numMutations;
- // recalculate the estimated size
- estimatedSize = PhoenixKeyValueUtil.getEstimatedRowMutationSizeWithBatch(this.mutationsMap);
- }
- areAllBatchesSuccessful = true;
- } catch (Exception e) {
- long serverTimestamp = ServerUtil.parseServerTimestamp(e);
- SQLException inferredE = ServerUtil.parseServerExceptionOrNull(e);
- if (inferredE != null) {
- if (shouldRetry
- && retryCount == 0
- && inferredE.getErrorCode() == SQLExceptionCode.INDEX_METADATA_NOT_FOUND
- .getErrorCode()) {
- // Swallow this exception once, as it's possible that we split after sending the index
- // metadata
- // and one of the region servers doesn't have it. This will cause it to have it the next
+ batchCount++;
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("Sent batch of " + mutationBatch.size() + " for "
+ + Bytes.toString(htableName));
+ }
+ shouldRetry = false;
+ numFailedMutations = 0;
+
+ // Remove batches as we process them
+ removeMutations(this.mutationsMap, origTableRef);
+ if (tableInfo.isDataTable()) {
+ numRows -= numMutations;
+ // recalculate the estimated size
+ estimatedSize = PhoenixKeyValueUtil.getEstimatedRowMutationSizeWithBatch(this.mutationsMap);
+ }
+ areAllBatchesSuccessful = true;
+ span.setStatus(StatusCode.OK);
+ } catch (Exception e) {
+ long serverTimestamp = ServerUtil.parseServerTimestamp(e);
+ SQLException inferredE = ServerUtil.parseServerExceptionOrNull(e);
+ if (inferredE != null) {
+ if (shouldRetry
+ && retryCount == 0
+ && inferredE.getErrorCode() == SQLExceptionCode.INDEX_METADATA_NOT_FOUND
+ .getErrorCode()) {
+ // Swallow this exception once, as it's possible that we split after sending the index
+ // metadata
+ // and one of the region servers doesn't have it. This will cause it to have it the next
// go around.
- // If it fails again, we don't retry.
- String msg = "Swallowing exception and retrying after clearing meta cache on connection. "
- + inferredE;
- LOGGER.warn(LogUtil.addCustomAnnotations(msg, connection));
- connection.getQueryServices().clearTableRegionCache(TableName.valueOf(htableName));
-
- // add a new child span as this one failed
- child.addTimelineAnnotation(msg);
- child.stop();
- child = Tracing.child(span, "Failed batch, attempting retry");
-
- continue;
- } else if (inferredE.getErrorCode() == SQLExceptionCode.INDEX_WRITE_FAILURE.getErrorCode()) {
- iwe = PhoenixIndexFailurePolicy.getIndexWriteException(inferredE);
- if (iwe != null && !shouldRetryIndexedMutation) {
- // For an index write failure, the data table write succeeded,
- // so when we retry we need to set REPLAY_WRITES
- // for first batch in list only.
- for (Mutation m : mutationBatchList.get(0)) {
- if (!PhoenixIndexMetaData.isIndexRebuild(
- m.getAttributesMap())){
- m.setAttribute(BaseScannerRegionObserver.REPLAY_WRITES,
- BaseScannerRegionObserver.REPLAY_ONLY_INDEX_WRITES
- );
+ // If it fails again, we don't retry.
+ String msg = "Swallowing exception and retrying after clearing meta cache on connection. "
+ + inferredE;
+ LOGGER.warn(LogUtil.addCustomAnnotations(msg, connection));
+ connection.getQueryServices().clearTableRegionCache(TableName.valueOf(htableName));
+
+ // The HTRace implementation started a new child span here.
+ // Now we're just adding an event to the same span.
+ span.addEvent(msg);
+ continue;
+ } else if (inferredE.getErrorCode() == SQLExceptionCode.INDEX_WRITE_FAILURE.getErrorCode()) {
+ iwe = PhoenixIndexFailurePolicy.getIndexWriteException(inferredE);
+ if (iwe != null && !shouldRetryIndexedMutation) {
+ // For an index write failure, the data table write succeeded,
+ // so when we retry we need to set REPLAY_WRITES
+ // for first batch in list only.
+ for (Mutation m : mutationBatchList.get(0)) {
+ if (!PhoenixIndexMetaData.isIndexRebuild(
+ m.getAttributesMap())){
+ m.setAttribute(BaseScannerRegionObserver.REPLAY_WRITES,
+ BaseScannerRegionObserver.REPLAY_ONLY_INDEX_WRITES
+ );
+ }
+ PhoenixKeyValueUtil.setTimestamp(m, serverTimestamp);
}
- PhoenixKeyValueUtil.setTimestamp(m, serverTimestamp);
+ shouldRetry = true;
+ shouldRetryIndexedMutation = true;
+ continue;
}
- shouldRetry = true;
- shouldRetryIndexedMutation = true;
- continue;
}
+ e = inferredE;
}
- e = inferredE;
- }
- // Throw to client an exception that indicates the statements that
- // were not committed successfully.
- int[] uncommittedStatementIndexes = getUncommittedStatementIndexes();
- sqlE = new CommitException(e, uncommittedStatementIndexes, serverTimestamp);
-
- numFailedMutations = uncommittedStatementIndexes.length;
-
- if (isVerifiedPhase) {
- numFailedPhase3Mutations = numFailedMutations;
- GLOBAL_MUTATION_INDEX_COMMIT_FAILURE_COUNT.update(numFailedPhase3Mutations);
- }
- } finally {
- mutationCommitTime = EnvironmentEdgeManager.currentTimeMillis() - startTime;
- GLOBAL_MUTATION_COMMIT_TIME.update(mutationCommitTime);
- MutationMetric failureMutationMetrics = MutationMetric.EMPTY_METRIC;
- if (!areAllBatchesSuccessful) {
- failureMutationMetrics =
- updateMutationBatchFailureMetrics(currentMutationBatch,
- htableNameStr, numFailedMutations,
- table.isTransactional());
- }
-
- MutationMetric committedMutationsMetric =
- getCommittedMutationsMetric(
- totalMutationBytesObject,
- mutationBatchList,
- numMutations,
- numFailedMutations,
- numFailedPhase3Mutations,
- mutationCommitTime);
- // Combine failure mutation metrics with committed ones for the final picture
- committedMutationsMetric.combineMetric(failureMutationMetrics);
- mutationMetricQueue.addMetricsForTable(htableNameStr, committedMutationsMetric);
-
- if (allUpsertsMutations ^ allDeletesMutations) {
- //success cases are updated for both cases autoCommit=true and conn.commit explicit
- if (areAllBatchesSuccessful){
- TableMetricsManager
- .updateMetricsMethod(htableNameStr, allUpsertsMutations ? UPSERT_AGGREGATE_SUCCESS_SQL_COUNTER :
- DELETE_AGGREGATE_SUCCESS_SQL_COUNTER, 1);
+ TraceUtil.setError(span, inferredE);
+ // Throw to client an exception that indicates the statements that
+ // were not committed successfully.
+ int[] uncommittedStatementIndexes = getUncommittedStatementIndexes();
+ sqlE = new CommitException(e, uncommittedStatementIndexes, serverTimestamp);
+ numFailedMutations = uncommittedStatementIndexes.length;
+
+ if (isVerifiedPhase) {
+ numFailedPhase3Mutations = numFailedMutations;
+ GLOBAL_MUTATION_INDEX_COMMIT_FAILURE_COUNT.update(numFailedPhase3Mutations);
}
- //Failures cases are updated only for conn.commit explicit case.
- if (!areAllBatchesSuccessful && !connection.getAutoCommit()){
- TableMetricsManager.updateMetricsMethod(htableNameStr, allUpsertsMutations ? UPSERT_AGGREGATE_FAILURE_SQL_COUNTER :
- DELETE_AGGREGATE_FAILURE_SQL_COUNTER, 1);
+ } finally {
+ mutationCommitTime = EnvironmentEdgeManager.currentTimeMillis() - startTime;
+ GLOBAL_MUTATION_COMMIT_TIME.update(mutationCommitTime);
+ MutationMetric failureMutationMetrics = MutationMetric.EMPTY_METRIC;
+ if (!areAllBatchesSuccessful) {
+ failureMutationMetrics =
+ updateMutationBatchFailureMetrics(currentMutationBatch,
+ htableNameStr, numFailedMutations,
+ table.isTransactional());
}
- // Update size and latency histogram metrics.
- TableMetricsManager.updateSizeHistogramMetricsForMutations(htableNameStr,
- committedMutationsMetric.getTotalMutationsSizeBytes().getValue(), allUpsertsMutations);
- Long latency = timeInExecuteMutationMap.get(htableNameStr);
- if (latency == null) {
- latency = 0l;
+
+ MutationMetric committedMutationsMetric =
+ getCommittedMutationsMetric(
+ totalMutationBytesObject,
+ mutationBatchList,
+ numMutations,
+ numFailedMutations,
+ numFailedPhase3Mutations,
+ mutationCommitTime);
+ // Combine failure mutation metrics with committed ones for the final picture
+ committedMutationsMetric.combineMetric(failureMutationMetrics);
+ mutationMetricQueue.addMetricsForTable(htableNameStr, committedMutationsMetric);
+
+ if (allUpsertsMutations ^ allDeletesMutations) {
+ //success cases are updated for both cases autoCommit=true and conn.commit explicit
+ if (areAllBatchesSuccessful){
+ TableMetricsManager
+ .updateMetricsMethod(htableNameStr, allUpsertsMutations ? UPSERT_AGGREGATE_SUCCESS_SQL_COUNTER :
+ DELETE_AGGREGATE_SUCCESS_SQL_COUNTER, 1);
+ }
+ //Failures cases are updated only for conn.commit explicit case.
+ if (!areAllBatchesSuccessful && !connection.getAutoCommit()){
+ TableMetricsManager.updateMetricsMethod(htableNameStr, allUpsertsMutations ? UPSERT_AGGREGATE_FAILURE_SQL_COUNTER :
+ DELETE_AGGREGATE_FAILURE_SQL_COUNTER, 1);
+ }
+ // Update size and latency histogram metrics.
+ TableMetricsManager.updateSizeHistogramMetricsForMutations(htableNameStr,
+ committedMutationsMetric.getTotalMutationsSizeBytes().getValue(), allUpsertsMutations);
+ Long latency = timeInExecuteMutationMap.get(htableNameStr);
+ if (latency == null) {
+ latency = 0l;
+ }
+ latency += mutationCommitTime;
+ TableMetricsManager.updateLatencyHistogramForMutations(htableNameStr,
+ latency, allUpsertsMutations);
}
- latency += mutationCommitTime;
- TableMetricsManager.updateLatencyHistogramForMutations(htableNameStr,
- latency, allUpsertsMutations);
- }
- resetAllMutationState();
+ resetAllMutationState();
- try {
- if (cache != null) cache.close();
- } finally {
try {
- hTable.close();
- } catch (IOException e) {
- if (sqlE != null) {
- sqlE.setNextException(ServerUtil.parseServerException(e));
- } else {
- sqlE = ServerUtil.parseServerException(e);
+ if (cache != null) cache.close();
+ } finally {
+ try {
+ hTable.close();
+ } catch (IOException e) {
+ if (sqlE != null) {
+ sqlE.setNextException(ServerUtil.parseServerException(e));
+ } else {
+ sqlE = ServerUtil.parseServerException(e);
+ }
}
+ if (sqlE != null) { throw sqlE; }
}
- if (sqlE != null) { throw sqlE; }
}
+ } finally {
+ span.end();
}
} while (shouldRetry && retryCount++ < 1);
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/IndexRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/IndexRegionObserver.java
index 593fdbe0d01..36263a389bd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/IndexRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/IndexRegionObserver.java
@@ -74,9 +74,6 @@
import org.apache.hadoop.hbase.wal.WALEdit;
import org.apache.hadoop.hbase.wal.WALKey;
import org.apache.hadoop.io.WritableUtils;
-import org.apache.htrace.Span;
-import org.apache.htrace.Trace;
-import org.apache.htrace.TraceScope;
import org.apache.phoenix.compile.ScanRanges;
import org.apache.phoenix.coprocessor.DelegateRegionCoprocessorEnvironment;
import org.apache.phoenix.coprocessor.generated.PTableProtos;
@@ -115,8 +112,7 @@
import org.apache.phoenix.schema.tuple.MultiKeyValueTuple;
import org.apache.phoenix.schema.transform.TransformMaintainer;
import org.apache.phoenix.schema.types.PVarbinary;
-import org.apache.phoenix.trace.TracingUtils;
-import org.apache.phoenix.trace.util.NullSpan;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.EnvironmentEdgeManager;
import org.apache.phoenix.util.IndexUtil;
@@ -127,6 +123,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -984,12 +984,9 @@ private void preparePreIndexMutations(BatchMutateContext context,
PhoenixIndexMetaData indexMetaData) throws Throwable {
List maintainers = indexMetaData.getIndexMaintainers();
// get the current span, or just use a null-span to avoid a bunch of if statements
- try (TraceScope scope = Trace.startSpan("Starting to build index updates")) {
- Span current = scope.getSpan();
- if (current == null) {
- current = NullSpan.INSTANCE;
- }
- current.addTimelineAnnotation("Built index updates, doing preStep");
+ Span span = TraceUtil.createServerSideSpan("Starting to build index updates");
+ try (Scope ignored = span.makeCurrent()) {
+ span.addEvent("Built index updates, doing preStep");
// The rest of this method is for handling global index updates
context.indexUpdates = ArrayListMultimap.>create();
prepareIndexMutations(context, maintainers, now);
@@ -1018,7 +1015,13 @@ private void preparePreIndexMutations(BatchMutateContext context,
}
}
}
- TracingUtils.addAnnotation(current, "index update count", updateCount);
+ span.setAttribute("index update count", updateCount);
+ span.setStatus(StatusCode.OK);
+ } catch (Throwable t) {
+ TraceUtil.setError(span, t);
+ throw t;
+ } finally {
+ span.end();
}
}
@@ -1361,18 +1364,20 @@ private void doIndexWritesWithExceptions(BatchMutateContext context, boolean pos
return;
}
- // get the current span, or just use a null-span to avoid a bunch of if statements
- try (TraceScope scope = Trace.startSpan("Completing " + (post ? "post" : "pre") + " index writes")) {
- Span current = scope.getSpan();
- if (current == null) {
- current = NullSpan.INSTANCE;
- }
- current.addTimelineAnnotation("Actually doing " + (post ? "post" : "pre") + " index update for first time");
+ Span span = TraceUtil.createServerSideSpan("Completing " + (post ? "post" : "pre") + " index writes");
+ try (Scope ignored = span.makeCurrent()) {
+ span.addEvent("Actually doing " + (post ? "post" : "pre") + " index update for first time");
if (post) {
postWriter.write(indexUpdates, false, context.clientVersion);
} else {
preWriter.write(indexUpdates, false, context.clientVersion);
}
+ span.setStatus(StatusCode.OK);
+ } catch (IOException e) {
+ TraceUtil.setError(span, e);
+ throw e;
+ } finally {
+ span.end();
}
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
index 4218dbc7b40..fbcb346a919 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
@@ -55,9 +55,6 @@
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.wal.WALEdit;
-import org.apache.htrace.Span;
-import org.apache.htrace.Trace;
-import org.apache.htrace.TraceScope;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver.ReplayWrite;
import org.apache.phoenix.coprocessor.DelegateRegionCoprocessorEnvironment;
import org.apache.phoenix.hbase.index.LockManager.RowLock;
@@ -77,8 +74,7 @@
import org.apache.phoenix.hbase.index.write.recovery.PerRegionIndexWriteCache;
import org.apache.phoenix.hbase.index.write.recovery.StoreFailuresInCachePolicy;
import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.trace.TracingUtils;
-import org.apache.phoenix.trace.util.NullSpan;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.util.EnvironmentEdgeManager;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.ScanUtil;
@@ -87,6 +83,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
import org.apache.phoenix.thirdparty.com.google.common.collect.Multimap;
@@ -489,11 +489,8 @@ public void preBatchMutateWithExceptions(ObserverContext> indexUpdatesItr = indexUpdates.iterator();
List localUpdates = new ArrayList(indexUpdates.size());
@@ -535,9 +532,15 @@ public void preBatchMutateWithExceptions(ObserverContext
return;
}
- // get the current span, or just use a null-span to avoid a bunch of if statements
- try (TraceScope scope = Trace.startSpan("Completing index writes")) {
- Span current = scope.getSpan();
- if (current == null) {
- current = NullSpan.INSTANCE;
- }
+ Span span = TraceUtil.createServerSideSpan("Completing index writes");
+ try (Scope ignored = span.makeCurrent()) {
long start = EnvironmentEdgeManager.currentTimeMillis();
- current.addTimelineAnnotation("Actually doing index update for first time");
+ span.addEvent("Actually doing index update for first time");
writer.writeAndHandleFailure(context.indexUpdates, false, context.clientVersion);
long duration = EnvironmentEdgeManager.currentTimeMillis() - start;
@@ -625,6 +624,12 @@ private void doPostWithExceptions(ObserverContext
metricSource.incrementNumSlowIndexWriteCalls(dataTableName);
}
metricSource.updateIndexWriteTime(dataTableName, duration);
+ span.end();
+ } catch (Throwable t) {
+ TraceUtil.setError(span, t);
+ throw t;
+ } finally {
+ span.end();
}
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/LockManager.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/LockManager.java
index cb5fd225188..8bce77267a2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/LockManager.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/LockManager.java
@@ -26,12 +26,15 @@
import java.util.concurrent.locks.ReentrantLock;
import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
-import org.apache.htrace.Trace;
-import org.apache.htrace.TraceScope;
import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
+import org.apache.phoenix.trace.TraceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
/**
*
* Class, copied for the most part from HRegion.getRowLockInternal implementation
@@ -60,16 +63,11 @@ public LockManager () {
public RowLock lockRow(ImmutableBytesPtr rowKey, int waitDuration) throws IOException {
RowLockContext rowLockContext = null;
RowLockImpl result = null;
- TraceScope traceScope = null;
-
- // If we're tracing start a span to show how long this took.
- if (Trace.isTracing()) {
- traceScope = Trace.startSpan("LockManager.getRowLock");
- traceScope.getSpan().addTimelineAnnotation("Getting a lock");
- }
boolean success = false;
- try {
+ Span span = TraceUtil.createServerSideSpan("LockManager.getRowLock");
+ try (Scope ignored = span.makeCurrent()){
+ span.addEvent("Getting a lock");
// Keep trying until we have a lock or error out.
// TODO: do we need to add a time component here?
while (result == null) {
@@ -87,29 +85,25 @@ public RowLock lockRow(ImmutableBytesPtr rowKey, int waitDuration) throws IOExce
result = rowLockContext.newRowLock();
}
if (!result.getLock().tryLock(waitDuration, TimeUnit.MILLISECONDS)) {
- if (traceScope != null) {
- traceScope.getSpan().addTimelineAnnotation("Failed to get row lock");
- }
+ span.addEvent("Failed to get row lock");
throw new TimeoutIOException("Timed out waiting for lock for row: " + rowKey);
}
rowLockContext.setThreadName(Thread.currentThread().getName());
success = true;
+ span.setStatus(StatusCode.OK);
return result;
} catch (InterruptedException ie) {
LOGGER.warn("Thread interrupted waiting for lock on row: " + rowKey);
InterruptedIOException iie = new InterruptedIOException();
iie.initCause(ie);
- if (traceScope != null) {
- traceScope.getSpan().addTimelineAnnotation("Interrupted exception getting row lock");
- }
+ span.addEvent("Interrupted exception getting row lock");
+ TraceUtil.setError(span, ie);
Thread.currentThread().interrupt();
throw iie;
} finally {
+ span.end();
// On failure, clean up the counts just in case this was the thing keeping the context alive.
if (!success && rowLockContext != null) rowLockContext.cleanUp();
- if (traceScope != null) {
- traceScope.close();
- }
}
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
index 914bf9fa3ee..00a6fc80f20 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
@@ -25,39 +25,34 @@
import java.util.List;
import java.util.Optional;
-import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
-import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionObserver;
-import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
-import org.apache.hadoop.hbase.ipc.controller.InterRegionServerIndexRpcControllerFactory;
import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
-import org.apache.htrace.Span;
-import org.apache.htrace.Trace;
-import org.apache.htrace.TraceScope;
import org.apache.phoenix.coprocessor.DelegateRegionCoprocessorEnvironment;
import org.apache.phoenix.coprocessor.MetaDataProtocol;
import org.apache.phoenix.execute.PhoenixTxIndexMutationGenerator;
import org.apache.phoenix.hbase.index.write.IndexWriter;
import org.apache.phoenix.hbase.index.write.LeaveIndexActiveFailurePolicy;
import org.apache.phoenix.hbase.index.write.ParallelWriterIndexCommitter;
-import org.apache.phoenix.trace.TracingUtils;
-import org.apache.phoenix.trace.util.NullSpan;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.transaction.PhoenixTransactionContext;
-import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.ServerUtil;
import org.apache.phoenix.util.ServerUtil.ConnectionType;
import org.apache.phoenix.util.TransactionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
/**
* Do all the work of managing local index updates for a transactional table from a single coprocessor. Since the transaction
* manager essentially time orders writes through conflict detection, the logic to maintain a secondary index is quite a
@@ -153,13 +148,8 @@ public void preBatchMutate(ObserverContext c,
setBatchMutateContext(c, context);
Collection> indexUpdates = null;
- // get the current span, or just use a null-span to avoid a bunch of if statements
- try (TraceScope scope = Trace.startSpan("Starting to build index updates")) {
- Span current = scope.getSpan();
- if (current == null) {
- current = NullSpan.INSTANCE;
- }
-
+ Span span = TraceUtil.createServerSideSpan("Starting to build index updates");
+ try (Scope ignored = span.makeCurrent()) {
RegionCoprocessorEnvironment env = c.getEnvironment();
PhoenixTransactionContext txnContext = indexMetaData.getTransactionContext();
if (txnContext == null) {
@@ -194,12 +184,16 @@ public void preBatchMutate(ObserverContext c,
context.indexUpdates = indexUpdates;
}
- current.addTimelineAnnotation("Built index updates, doing preStep");
- TracingUtils.addAnnotation(current, "index update count", context.indexUpdates.size());
+ span.addEvent("Built index updates, doing preStep");
+ span.setAttribute("index update count", context.indexUpdates.size());
+ span.setStatus(StatusCode.OK);
} catch (Throwable t) {
+ TraceUtil.setError(span, t);
String msg = "Failed to update index with entries:" + indexUpdates;
LOGGER.error(msg, t);
ServerUtil.throwIOException(msg, t);
+ } finally {
+ span.end();
}
}
@@ -210,24 +204,22 @@ public void postBatchMutateIndispensably(ObserverContext> nestedScans, List future = executor.submit(Tracing.wrap(new JobCallable() {
+ Future future = executor.submit(TraceUtil.wrap(new JobCallable() {
@Override
public PeekingResultIterator call() throws Exception {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
index ff394a36871..0e3f3cebc27 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
@@ -43,7 +43,7 @@
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.schema.types.PInteger;
-import org.apache.phoenix.trace.util.Tracing;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.util.QueryUtil;
import org.apache.phoenix.thirdparty.com.google.common.base.Preconditions;
@@ -97,7 +97,7 @@ protected void submitWork(final List> nestedScans, List finalScans = flattenedScans;
- Future future = executor.submit(Tracing.wrap(new JobCallable() {
+ Future future = executor.submit(TraceUtil.wrap(new JobCallable() {
@Override
public PeekingResultIterator call() throws Exception {
PeekingResultIterator itr = new SerialIterator(finalScans, tableName, renewLeaseThreshold, offset, caches, maxQueryEndTime);
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index c7afcb0b9e9..5c962dfcaf9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -50,7 +50,6 @@
import java.sql.Statement;
import java.sql.Struct;
import java.text.Format;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -67,9 +66,6 @@
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.Consistency;
-import org.apache.htrace.Sampler;
-import org.apache.htrace.TraceScope;
-import org.apache.phoenix.call.CallRunner;
import org.apache.phoenix.exception.FailoverSQLException;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
@@ -119,12 +115,6 @@
import org.apache.phoenix.schema.types.PUnsignedTime;
import org.apache.phoenix.schema.types.PUnsignedTimestamp;
import org.apache.phoenix.schema.types.PVarbinary;
-import org.apache.phoenix.thirdparty.com.google.common.annotations.VisibleForTesting;
-import org.apache.phoenix.thirdparty.com.google.common.base.Objects;
-import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
-import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableMap;
-import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableMap.Builder;
-import org.apache.phoenix.trace.util.Tracing;
import org.apache.phoenix.transaction.PhoenixTransactionContext;
import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.EnvironmentEdgeManager;
@@ -138,6 +128,17 @@
import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.util.VarBinaryFormatter;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
+import org.apache.phoenix.thirdparty.com.google.common.annotations.VisibleForTesting;
+import org.apache.phoenix.thirdparty.com.google.common.base.Objects;
+import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
+import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableMap;
+import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableMap.Builder;
+import org.apache.phoenix.trace.NullScope;
+import org.apache.phoenix.trace.TraceUtil;
/**
*
* JDBC Connection implementation of Phoenix. Currently the following are
@@ -168,10 +169,9 @@ public class PhoenixConnection implements MetaDataMutated, SQLCloseable, Phoenix
private final String timePattern;
private final String timestampPattern;
private int statementExecutionCounter;
- private TraceScope traceScope = null;
+ private Span manualTraceSpan;
private volatile boolean isClosed = false;
private volatile boolean isClosing = false;
- private Sampler> sampler;
private boolean readOnly = false;
private Consistency consistency = Consistency.STRONG;
private Map customTracingAnnotations = emptyMap();
@@ -199,7 +199,6 @@ public class PhoenixConnection implements MetaDataMutated, SQLCloseable, Phoenix
private ConnectionActivityLogger connectionActivityLogger = ConnectionActivityLogger.NO_OP_LOGGER;
static {
- Tracing.addTraceMetricsSource();
CONNECTION_PROPERTIES = PhoenixRuntime.getConnectionProperties();
}
@@ -209,6 +208,7 @@ private static Properties newPropsWithSCN(long scn, Properties props) {
return props;
}
+ //TODO handle active Tracing span for copy constructors
public PhoenixConnection(PhoenixConnection connection,
boolean isDescRowKeyOrderUpgrade, boolean isRunningUpgrade)
throws SQLException {
@@ -218,7 +218,6 @@ public PhoenixConnection(PhoenixConnection connection,
isRunningUpgrade, connection.buildingIndex, true);
this.isAutoCommit = connection.isAutoCommit;
this.isAutoFlush = connection.isAutoFlush;
- this.sampler = connection.sampler;
this.statementExecutionCounter = connection.statementExecutionCounter;
}
@@ -246,7 +245,6 @@ public PhoenixConnection(PhoenixConnection connection, Properties props) throws
connection.isRunningUpgrade(), connection.buildingIndex, true);
this.isAutoCommit = connection.isAutoCommit;
this.isAutoFlush = connection.isAutoFlush;
- this.sampler = connection.sampler;
this.statementExecutionCounter = connection.statementExecutionCounter;
}
@@ -388,7 +386,6 @@ public ReadOnlyProps getProps() {
this.services.addConnection(this);
// setup tracing, if its enabled
- this.sampler = Tracing.getConfiguredSampler(this);
this.customTracingAnnotations = getImmutableCustomTracingAnnotations();
this.scannerQueue = new LinkedBlockingQueue<>();
this.tableResultIteratorFactory = new DefaultTableResultIteratorFactory();
@@ -481,6 +478,7 @@ public boolean isInternalConnection() {
* @param connection
*/
public void addChildConnection(PhoenixConnection connection) {
+ //TODO handle trace pan
childConnections.add(connection);
}
@@ -490,6 +488,7 @@ public void addChildConnection(PhoenixConnection connection) {
* @param connection
*/
public void removeChildConnection(PhoenixConnection connection) {
+ //TODO handle trace span
childConnections.remove(connection);
}
@@ -503,14 +502,6 @@ public int getChildConnectionsCount() {
return childConnections.size();
}
- public Sampler> getSampler() {
- return this.sampler;
- }
-
- public void setSampler(Sampler> sampler) throws SQLException {
- this.sampler = sampler;
- }
-
public Map getCustomTracingAnnotations() {
return customTracingAnnotations;
}
@@ -781,12 +772,13 @@ synchronized public void close() throws SQLException {
clearMetrics();
}
try {
+
closeStatements();
if (childConnections != null) {
SQLCloseables.closeAllQuietly(childConnections);
}
- if (traceScope != null) {
- traceScope.close();
+ if (manualTraceSpan != null) {
+ manualTraceSpan.end();
}
} finally {
services.removeConnection(this);
@@ -819,18 +811,18 @@ synchronized public void close() throws SQLException {
@Override
public void commit() throws SQLException {
- CallRunner.run(new CallRunner.CallableThrowable() {
- @Override
- public Void call() throws SQLException {
- checkOpen();
- try {
- mutationState.commit();
- } finally {
- mutationState.resetExecuteMutationTimeMap();
- }
- return null;
- }
- }, Tracing.withTracing(this, "committing mutations"));
+ checkOpen();
+ Span span = TraceUtil.createSpan(this, "committing mutations");
+ try (Scope ignored = span.makeCurrent()) {
+ mutationState.commit();
+ span.setStatus(StatusCode.OK);
+ } catch (Exception e) {
+ TraceUtil.setError(span, e);
+ throw e;
+ } finally {
+ span.end();
+ mutationState.resetExecuteMutationTimeMap();
+ }
statementExecutionCounter = 0;
}
@@ -1116,14 +1108,19 @@ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
@Override
public void rollback() throws SQLException {
- CallRunner.run(new CallRunner.CallableThrowable() {
- @Override
- public Void call() throws SQLException {
- checkOpen();
+ if (!mutationState.isEmpty()) {
+ checkOpen();
+ Span span = TraceUtil.createSpan(this, "rolling back");
+ try (Scope scope = span.makeCurrent()) {
mutationState.rollback();
- return null;
+ span.setStatus(StatusCode.OK);
+ } catch (Exception e) {
+ TraceUtil.setError(span, e);
+ throw e;
+ } finally {
+ span.end();
}
- }, Tracing.withTracing(this, "rolling back"));
+ }
statementExecutionCounter = 0;
}
@@ -1343,14 +1340,6 @@ public void incrementStatementExecutionCounter() {
}
}
- public TraceScope getTraceScope() {
- return traceScope;
- }
-
- public void setTraceScope(TraceScope traceScope) {
- this.traceScope = traceScope;
- }
-
@Override
public Map> getMutationMetrics() {
return mutationState.getMutationMetricQueue().aggregate();
@@ -1485,4 +1474,45 @@ public ConnectionActivityLogger getActivityLogger() {
public void setActivityLogger(ConnectionActivityLogger connectionActivityLogger) {
this.connectionActivityLogger = connectionActivityLogger;
}
+
+ public synchronized void startManualTraceSpan() {
+ if (manualTraceSpan != null) {
+ // TODO What to do if we try turn on tracing for a connection that is already on ?
+ // For now we just ignore it, but it may be better to throw an exception ?
+ return;
+ }
+ manualTraceSpan = TraceUtil.createSpan(this, "PhoenixConnection manual trace", true);
+ }
+
+ public synchronized void endManualTraceSpan() {
+ if (manualTraceSpan == null) {
+ // TODO What to do if we try turn off tracing for a connection that is already off ?
+ // For now we just ignore it, but it may be better to throw an exception ?
+ return;
+ }
+ // FIXME: If we still have traced queries running (i.e. open ResultSets), then events after
+ // this will be parent less, or at least those spans will be truncated.
+ // I don't see a way to avoid that, though.
+ try {
+ manualTraceSpan.end();
+ } finally {
+ manualTraceSpan = null;
+ }
+ }
+
+ public Scope makeCurrent() {
+ if (manualTraceSpan == null) {
+ return NullScope.INSTANCE;
+ } else {
+ return manualTraceSpan.makeCurrent();
+ }
+ }
+
+ public String getManualTraceSpanId() {
+ if (manualTraceSpan == null) {
+ return null;
+ } else {
+ return manualTraceSpan.getSpanContext().getSpanId();
+ }
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index 112cabd7d24..f27039a8e34 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -77,7 +77,12 @@
import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.util.StringUtil;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
+import org.apache.phoenix.trace.TraceUtil;
/**
*
@@ -762,204 +767,205 @@ private boolean match(String str, String pattern) throws SQLException {
}
@Override
- public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
- throws SQLException {
- try {
- boolean isTenantSpecificConnection = connection.getTenantId() != null;
+ public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern,
+ String columnNamePattern) throws SQLException {
List tuples = Lists.newArrayListWithExpectedSize(10);
- // Allow a "." in columnNamePattern for column family match
- String colPattern = null;
- String cfPattern = null;
- if (columnNamePattern != null && columnNamePattern.length() > 0) {
- int index = columnNamePattern.indexOf('.');
- if (index <= 0) {
- colPattern = columnNamePattern;
- } else {
- cfPattern = columnNamePattern.substring(0, index);
- if (columnNamePattern.length() > index+1) {
- colPattern = columnNamePattern.substring(index+1);
+ Span span = TraceUtil.createSpan(connection, "PhoenixDataBaseMetaData.getColumns() collecting data");
+ try (Scope ignored = span.makeCurrent()) {
+ boolean isTenantSpecificConnection = connection.getTenantId() != null;
+ // Allow a "." in columnNamePattern for column family match
+ String colPattern = null;
+ String cfPattern = null;
+ if (columnNamePattern != null && columnNamePattern.length() > 0) {
+ int index = columnNamePattern.indexOf('.');
+ if (index <= 0) {
+ colPattern = columnNamePattern;
+ } else {
+ cfPattern = columnNamePattern.substring(0, index);
+ if (columnNamePattern.length() > index + 1) {
+ colPattern = columnNamePattern.substring(index + 1);
+ }
}
}
- }
- try (ResultSet rs = getTables(catalog, schemaPattern, tableNamePattern, null)) {
- while (rs.next()) {
- String schemaName = rs.getString(TABLE_SCHEM);
- String tableName = rs.getString(TABLE_NAME);
- String tenantId = rs.getString(TABLE_CAT);
- String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
- PTable table = PhoenixRuntime.getTableNoCache(connection, fullTableName);
- boolean isSalted = table.getBucketNum()!=null;
- boolean tenantColSkipped = false;
- List columns = table.getColumns();
- int startOffset = isSalted ? 1 : 0;
- columns = Lists.newArrayList(columns.subList(startOffset, columns.size()));
- for (PColumn column : columns) {
+ try (ResultSet rs = getTables(catalog, schemaPattern, tableNamePattern, null)) {
+ while (rs.next()) {
+ String schemaName = rs.getString(TABLE_SCHEM);
+ String tableName = rs.getString(TABLE_NAME);
+ String tenantId = rs.getString(TABLE_CAT);
+ String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
+ PTable table = PhoenixRuntime.getTableNoCache(connection, fullTableName);
+ boolean isSalted = table.getBucketNum() != null;
+ boolean tenantColSkipped = false;
+ List columns = table.getColumns();
+ int startOffset = isSalted ? 1 : 0;
+ columns = Lists.newArrayList(columns.subList(startOffset, columns.size()));
+ for (PColumn column : columns) {
if (isTenantSpecificConnection && column.equals(table.getPKColumns().get(startOffset))) {
- // skip the tenant column
- tenantColSkipped = true;
- continue;
- }
+ // skip the tenant column
+ tenantColSkipped = true;
+ continue;
+ }
String columnFamily = column.getFamilyName()!=null ? column.getFamilyName().getString() : null;
- String columnName = column.getName().getString();
+ String columnName = column.getName().getString();
if (cfPattern != null && cfPattern.length() > 0) { // if null or empty, will pick up all columns
- if (columnFamily==null || !match(columnFamily, cfPattern)) {
- continue;
+ if (columnFamily == null || !match(columnFamily, cfPattern)) {
+ continue;
+ }
}
- }
- if (colPattern != null && colPattern.length() > 0) {
- if (!match(columnName, colPattern)) {
- continue;
+ if (colPattern != null && colPattern.length() > 0) {
+ if (!match(columnName, colPattern)) {
+ continue;
+ }
}
- }
- // generate row key
- // TENANT_ID, TABLE_SCHEM, TABLE_NAME , COLUMN_NAME are row key columns
- byte[] rowKey =
- SchemaUtil.getColumnKey(tenantId, schemaName, tableName, columnName, null);
-
- // add one cell for each column info
- List cells = Lists.newArrayListWithCapacity(25);
- // DATA_TYPE
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- DATA_TYPE_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- PInteger.INSTANCE.toBytes(column.getDataType().getResultSetSqlType())));
- // TYPE_NAME
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(TYPE_NAME), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- column.getDataType().getSqlTypeNameBytes()));
- // COLUMN_SIZE
- cells.add(
- PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, COLUMN_SIZE_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ // generate row key
+ // TENANT_ID, TABLE_SCHEM, TABLE_NAME , COLUMN_NAME are row key columns
+ byte[] rowKey =
+ SchemaUtil.getColumnKey(tenantId, schemaName, tableName, columnName,
+ null);
+
+ // add one cell for each column info
+ List cells = Lists.newArrayListWithCapacity(25);
+ // DATA_TYPE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ DATA_TYPE_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PInteger.INSTANCE.toBytes(column.getDataType().getResultSetSqlType())));
+ // TYPE_NAME
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(TYPE_NAME), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getDataType().getSqlTypeNameBytes()));
+ // COLUMN_SIZE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ COLUMN_SIZE_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
column.getMaxLength() != null
? PInteger.INSTANCE.toBytes(column.getMaxLength())
: ByteUtil.EMPTY_BYTE_ARRAY));
- // BUFFER_LENGTH
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(BUFFER_LENGTH), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // DECIMAL_DIGITS
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- DECIMAL_DIGITS_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- column.getScale() != null ? PInteger.INSTANCE.toBytes(column.getScale())
- : ByteUtil.EMPTY_BYTE_ARRAY));
- // NUM_PREC_RADIX
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(NUM_PREC_RADIX), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // NULLABLE
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- NULLABLE_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- PInteger.INSTANCE.toBytes(SchemaUtil.getIsNullableInt(column.isNullable()))));
- // REMARKS
- cells.add(
- PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(REMARKS),
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, ByteUtil.EMPTY_BYTE_ARRAY));
- // COLUMN_DEF
- cells.add(
- PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(COLUMN_DEF),
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ // BUFFER_LENGTH
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(BUFFER_LENGTH), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // DECIMAL_DIGITS
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ DECIMAL_DIGITS_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getScale() != null ? PInteger.INSTANCE.toBytes(column.getScale())
+ : ByteUtil.EMPTY_BYTE_ARRAY));
+ // NUM_PREC_RADIX
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(NUM_PREC_RADIX), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // NULLABLE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ NULLABLE_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PInteger.INSTANCE
+ .toBytes(SchemaUtil.getIsNullableInt(column.isNullable()))));
+ // REMARKS
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(REMARKS), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // COLUMN_DEF
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(COLUMN_DEF), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
PVarchar.INSTANCE.toBytes(column.getExpressionStr())));
- // SQL_DATA_TYPE
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(SQL_DATA_TYPE), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // SQL_DATETIME_SUB
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(SQL_DATETIME_SUB), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // CHAR_OCTET_LENGTH
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(CHAR_OCTET_LENGTH), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // ORDINAL_POSITION
- int ordinal =
- column.getPosition() + (isSalted ? 0 : 1) - (tenantColSkipped ? 1 : 0);
- cells.add(
- PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- ORDINAL_POSITION_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, PInteger.INSTANCE.toBytes(ordinal)));
- String isNullable =
- column.isNullable() ? Boolean.TRUE.toString() : Boolean.FALSE.toString();
- // IS_NULLABLE
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(IS_NULLABLE), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- PVarchar.INSTANCE.toBytes(isNullable)));
- // SCOPE_CATALOG
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(SCOPE_CATALOG), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // SCOPE_SCHEMA
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(SCOPE_SCHEMA), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // SCOPE_TABLE
- cells.add(
- PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(SCOPE_TABLE),
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, ByteUtil.EMPTY_BYTE_ARRAY));
- // SOURCE_DATA_TYPE
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(SOURCE_DATA_TYPE), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // IS_AUTOINCREMENT
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(IS_AUTOINCREMENT), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- ByteUtil.EMPTY_BYTE_ARRAY));
- // ARRAY_SIZE
- cells.add(
- PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, ARRAY_SIZE_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ // SQL_DATA_TYPE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(SQL_DATA_TYPE), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // SQL_DATETIME_SUB
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(SQL_DATETIME_SUB), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // CHAR_OCTET_LENGTH
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(CHAR_OCTET_LENGTH), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // ORDINAL_POSITION
+ int ordinal =
+ column.getPosition() + (isSalted ? 0 : 1)
+ - (tenantColSkipped ? 1 : 0);
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ ORDINAL_POSITION_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PInteger.INSTANCE.toBytes(ordinal)));
+ String isNullable =
+ column.isNullable() ? Boolean.TRUE.toString()
+ : Boolean.FALSE.toString();
+ // IS_NULLABLE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(IS_NULLABLE), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PVarchar.INSTANCE.toBytes(isNullable)));
+ // SCOPE_CATALOG
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(SCOPE_CATALOG), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // SCOPE_SCHEMA
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(SCOPE_SCHEMA), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // SCOPE_TABLE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(SCOPE_TABLE), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // SOURCE_DATA_TYPE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(SOURCE_DATA_TYPE), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // IS_AUTOINCREMENT
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(IS_AUTOINCREMENT), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ ByteUtil.EMPTY_BYTE_ARRAY));
+ // ARRAY_SIZE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ ARRAY_SIZE_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
column.getArraySize() != null
? PInteger.INSTANCE.toBytes(column.getArraySize())
: ByteUtil.EMPTY_BYTE_ARRAY));
- // COLUMN_FAMILY
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- COLUMN_FAMILY_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, column.getFamilyName() != null
- ? column.getFamilyName().getBytes() : ByteUtil.EMPTY_BYTE_ARRAY));
- // TYPE_ID
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(TYPE_ID), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- PInteger.INSTANCE.toBytes(column.getDataType().getSqlType())));
- // VIEW_CONSTANT
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- VIEW_CONSTANT_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, column.getViewConstant() != null
- ? column.getViewConstant() : ByteUtil.EMPTY_BYTE_ARRAY));
- // MULTI_TENANT
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- MULTI_TENANT_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- PBoolean.INSTANCE.toBytes(table.isMultiTenant())));
- // KEY_SEQ_COLUMN
- byte[] keySeqBytes = ByteUtil.EMPTY_BYTE_ARRAY;
- int pkPos = table.getPKColumns().indexOf(column);
- if (pkPos!=-1) {
- short keySeq = (short) (pkPos + 1 - startOffset - (tenantColSkipped ? 1 : 0));
- keySeqBytes = PSmallint.INSTANCE.toBytes(keySeq);
+ // COLUMN_FAMILY
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ COLUMN_FAMILY_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getFamilyName() != null ? column.getFamilyName().getBytes()
+ : ByteUtil.EMPTY_BYTE_ARRAY));
+ // TYPE_ID
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(TYPE_ID), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PInteger.INSTANCE.toBytes(column.getDataType().getSqlType())));
+ // VIEW_CONSTANT
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ VIEW_CONSTANT_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getViewConstant() != null ? column.getViewConstant()
+ : ByteUtil.EMPTY_BYTE_ARRAY));
+ // MULTI_TENANT
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ MULTI_TENANT_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PBoolean.INSTANCE.toBytes(table.isMultiTenant())));
+ // KEY_SEQ_COLUMN
+ byte[] keySeqBytes = ByteUtil.EMPTY_BYTE_ARRAY;
+ int pkPos = table.getPKColumns().indexOf(column);
+ if (pkPos != -1) {
+ short keySeq =
+ (short) (pkPos + 1 - startOffset - (tenantColSkipped ? 1 : 0));
+ keySeqBytes = PSmallint.INSTANCE.toBytes(keySeq);
+ }
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ KEY_SEQ_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP, keySeqBytes));
+ Collections.sort(cells, new CellComparatorImpl());
+ Tuple tuple = new MultiKeyValueTuple(cells);
+ tuples.add(tuple);
}
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, KEY_SEQ_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, keySeqBytes));
- Collections.sort(cells, new CellComparatorImpl());
- Tuple tuple = new MultiKeyValueTuple(cells);
- tuples.add(tuple);
}
}
- }
-
- PhoenixStatement stmt = new PhoenixStatement(connection);
- stmt.closeOnCompletion();
- return new PhoenixResultSet(new MaterializedResultIterator(tuples), GET_COLUMNS_ROW_PROJECTOR, new StatementContext(stmt, false));
+ span.setStatus(StatusCode.OK);
+ } catch (Exception e) {
+ TraceUtil.setError(span, e);
+ throw e;
} finally {
if (connection.getAutoCommit()) {
- connection.commit();
+ try (Scope ignored = span.makeCurrent()) {
+ connection.commit();
+ }
}
+ span.end();
}
+ PhoenixStatement stmt = new PhoenixStatement(connection);
+ stmt.closeOnCompletion();
+ return new PhoenixResultSet(new MaterializedResultIterator(tuples),
+ GET_COLUMNS_ROW_PROJECTOR, new StatementContext(stmt, false));
}
@Override
@@ -1182,93 +1188,103 @@ public ResultSet getPrimaryKeys(String catalog, String schemaName, String tableN
if (tableName == null || tableName.length() == 0) {
return getEmptyResultSet();
}
- String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
- PTable table = PhoenixRuntime.getTableNoCache(connection, fullTableName);
- boolean isSalted = table.getBucketNum() != null;
- boolean tenantColSkipped = false;
- List pkColumns = table.getPKColumns();
- List sorderPkColumns =
- Lists.newArrayList(pkColumns.subList(isSalted ? 1 : 0, pkColumns.size()));
- // sort the columns by name
- Collections.sort(sorderPkColumns, new Comparator(){
- @Override public int compare(PColumn c1, PColumn c2) {
- return c1.getName().getString().compareTo(c2.getName().getString());
- }
- });
-
- try {
List tuples = Lists.newArrayListWithExpectedSize(10);
- try (ResultSet rs = getTables(catalog, schemaName, tableName, null)) {
- while (rs.next()) {
- String tenantId = rs.getString(TABLE_CAT);
- for (PColumn column : sorderPkColumns) {
- String columnName = column.getName().getString();
- // generate row key
- // TENANT_ID, TABLE_SCHEM, TABLE_NAME , COLUMN_NAME are row key columns
- byte[] rowKey =
- SchemaUtil.getColumnKey(tenantId, schemaName, tableName, columnName, null);
-
- // add one cell for each column info
- List cells = Lists.newArrayListWithCapacity(8);
- // KEY_SEQ_COLUMN
- byte[] keySeqBytes = ByteUtil.EMPTY_BYTE_ARRAY;
- int pkPos = pkColumns.indexOf(column);
- if (pkPos != -1) {
- short keySeq =
- (short) (pkPos + 1 - (isSalted ? 1 : 0) - (tenantColSkipped ? 1 : 0));
- keySeqBytes = PSmallint.INSTANCE.toBytes(keySeq);
- }
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, KEY_SEQ_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, keySeqBytes));
- // PK_NAME
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, PK_NAME_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, table.getPKName() != null
- ? table.getPKName().getBytes() : ByteUtil.EMPTY_BYTE_ARRAY));
- // ASC_OR_DESC
- char sortOrder = column.getSortOrder() == SortOrder.ASC ? 'A' : 'D';
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- ASC_OR_DESC_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- Bytes.toBytes(sortOrder)));
- // DATA_TYPE
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, DATA_TYPE_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- PInteger.INSTANCE.toBytes(column.getDataType().getResultSetSqlType())));
- // TYPE_NAME
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(TYPE_NAME), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- column.getDataType().getSqlTypeNameBytes()));
- // COLUMN_SIZE
- cells.add(
- PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, COLUMN_SIZE_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ Span span = TraceUtil.createSpan(connection, "PhoenixDataBaseMetaData.getPrimaryKeys() collecting data");
+ try (Scope ignored = span.makeCurrent()) {
+ String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
+ PTable table = PhoenixRuntime.getTableNoCache(connection, fullTableName);
+ boolean isSalted = table.getBucketNum() != null;
+ boolean tenantColSkipped = false;
+ List pkColumns = table.getPKColumns();
+ List sorderPkColumns =
+ Lists.newArrayList(pkColumns.subList(isSalted ? 1 : 0, pkColumns.size()));
+ // sort the columns by name
+ Collections.sort(sorderPkColumns, new Comparator() {
+ @Override
+ public int compare(PColumn c1, PColumn c2) {
+ return c1.getName().getString().compareTo(c2.getName().getString());
+ }
+ });
+ try (ResultSet rs = getTables(catalog, schemaName, tableName, null)) {
+ while (rs.next()) {
+ String tenantId = rs.getString(TABLE_CAT);
+ for (PColumn column : sorderPkColumns) {
+ String columnName = column.getName().getString();
+ // generate row key
+ // TENANT_ID, TABLE_SCHEM, TABLE_NAME , COLUMN_NAME are row key columns
+ byte[] rowKey =
+ SchemaUtil.getColumnKey(tenantId, schemaName, tableName, columnName,
+ null);
+
+ // add one cell for each column info
+ List cells = Lists.newArrayListWithCapacity(8);
+ // KEY_SEQ_COLUMN
+ byte[] keySeqBytes = ByteUtil.EMPTY_BYTE_ARRAY;
+ int pkPos = pkColumns.indexOf(column);
+ if (pkPos != -1) {
+ short keySeq =
+ (short) (pkPos + 1 - (isSalted ? 1 : 0)
+ - (tenantColSkipped ? 1 : 0));
+ keySeqBytes = PSmallint.INSTANCE.toBytes(keySeq);
+ }
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ KEY_SEQ_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP, keySeqBytes));
+ // PK_NAME
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ PK_NAME_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ table.getPKName() != null ? table.getPKName().getBytes()
+ : ByteUtil.EMPTY_BYTE_ARRAY));
+ // ASC_OR_DESC
+ char sortOrder = column.getSortOrder() == SortOrder.ASC ? 'A' : 'D';
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ ASC_OR_DESC_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ Bytes.toBytes(sortOrder)));
+ // DATA_TYPE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ DATA_TYPE_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PInteger.INSTANCE.toBytes(column.getDataType().getResultSetSqlType())));
+ // TYPE_NAME
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(TYPE_NAME), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getDataType().getSqlTypeNameBytes()));
+ // COLUMN_SIZE
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ COLUMN_SIZE_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
column.getMaxLength() != null
? PInteger.INSTANCE.toBytes(column.getMaxLength())
: ByteUtil.EMPTY_BYTE_ARRAY));
- // TYPE_ID
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
- Bytes.toBytes(TYPE_ID), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
- PInteger.INSTANCE.toBytes(column.getDataType().getSqlType())));
- // VIEW_CONSTANT
- cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES, VIEW_CONSTANT_BYTES,
- MetaDataProtocol.MIN_TABLE_TIMESTAMP, column.getViewConstant() != null
- ? column.getViewConstant() : ByteUtil.EMPTY_BYTE_ARRAY));
- Collections.sort(cells, new CellComparatorImpl());
- Tuple tuple = new MultiKeyValueTuple(cells);
- tuples.add(tuple);
+ // TYPE_ID
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ Bytes.toBytes(TYPE_ID), MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ PInteger.INSTANCE.toBytes(column.getDataType().getSqlType())));
+ // VIEW_CONSTANT
+ cells.add(PhoenixKeyValueUtil.newKeyValue(rowKey, TABLE_FAMILY_BYTES,
+ VIEW_CONSTANT_BYTES, MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+ column.getViewConstant() != null ? column.getViewConstant()
+ : ByteUtil.EMPTY_BYTE_ARRAY));
+ Collections.sort(cells, new CellComparatorImpl());
+ Tuple tuple = new MultiKeyValueTuple(cells);
+ tuples.add(tuple);
+ }
+ }
+ }
+ span.setStatus(StatusCode.OK);
+ } catch (Exception e) {
+ TraceUtil.setError(span, e);
+ throw e;
+ }finally {
+ if (connection.getAutoCommit()) {
+ try (Scope ignored = span.makeCurrent()) {
+ connection.commit();
}
}
+ span.end();
}
-
+ //The statement Trace span is long lived, it must not overlap with the previous one.
PhoenixStatement stmt = new PhoenixStatement(connection);
stmt.closeOnCompletion();
return new PhoenixResultSet(new MaterializedResultIterator(tuples),
- GET_PRIMARY_KEYS_ROW_PROJECTOR,
- new StatementContext(stmt, false));
- } finally {
- if (connection.getAutoCommit()) {
- connection.commit();
- }
- }
+ GET_PRIMARY_KEYS_ROW_PROJECTOR, new StatementContext(stmt, false));
}
@Override
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java
index 9a00f9bbe56..891d071839e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java
@@ -166,7 +166,7 @@ void executeForBatch() throws SQLException {
SQLExceptionCode.EXECUTE_BATCH_FOR_STMT_WITH_RESULT_SET)
.build().buildException();
}
- executeMutation(statement, createAuditQueryLogger(statement, query));
+ executeMutation(statement, createAuditQueryLogger(statement, query), query);
}
@Override
@@ -178,7 +178,7 @@ public boolean execute() throws SQLException {
.build().buildException();
}
if (statement.getOperation().isMutation()) {
- executeMutation(statement, createAuditQueryLogger(statement,query));
+ executeMutation(statement, createAuditQueryLogger(statement,query), query);
return false;
}
executeQuery(statement, createQueryLogger(statement,query));
@@ -205,7 +205,7 @@ public int executeUpdate() throws SQLException {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.EXECUTE_UPDATE_WITH_NON_EMPTY_BATCH)
.build().buildException();
}
- return executeMutation(statement, createAuditQueryLogger(statement,query));
+ return executeMutation(statement, createAuditQueryLogger(statement,query), query);
}
public QueryPlan optimizeQuery() throws SQLException {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
index 8e91d90447d..f0cd0ef6edc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
@@ -51,7 +51,13 @@
import org.apache.phoenix.monitoring.TableMetricsManager;
import org.apache.phoenix.thirdparty.com.google.common.primitives.Bytes;
+import org.apache.phoenix.trace.TraceUtil;
+
import com.google.protobuf.InvalidProtocolBufferException;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Scope;
+
import org.apache.commons.lang3.ArrayUtils;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
@@ -166,7 +172,7 @@ public class PhoenixResultSet implements PhoenixMonitoredResultSet, SQLCloseable
private Object exception;
private long queryTime;
private final Calendar localCalendar;
-
+
public PhoenixResultSet(ResultIterator resultIterator, RowProjector rowProjector,
StatementContext ctx) throws SQLException {
this.rowProjector = rowProjector;
@@ -221,9 +227,15 @@ public void close() throws SQLException {
if (isClosed) {
return;
}
- try {
+ Span span = statement.getLastQuerySpan();
+ // lastQuerySpan may be null for synthetic resultsets
+ try (Scope ignored = (span == null) ? Scope.noop() : span.makeCurrent()) {
scanner.close();
} finally {
+ //TODO should we move this to the end of this block ?
+ if (span != null) {
+ span.end();
+ }
isClosed = true;
statement.removeResultSet(this);
overAllQueryMetrics.endQuery();
@@ -875,10 +887,13 @@ public Tuple getCurrentRow() {
@Override
public boolean next() throws SQLException {
checkOpen();
- try {
+ Span span = statement.getLastQuerySpan();
+ //TODO can we have null lastQuerySpan when calling next() ?
+ try (Scope ignored = (span == null) ? Scope.noop() : span.makeCurrent()) {
if (!firstRecordRead) {
firstRecordRead = true;
overAllQueryMetrics.startResultSetWatch();
+ span.addEvent("first Result of ResultSet read");
}
currentRow = scanner.next();
if (currentRow != null) {
@@ -901,6 +916,7 @@ public boolean next() throws SQLException {
queryLogger.log(QueryLogInfo.EXCEPTION_TRACE_I, Throwables.getStackTraceAsString(e));
}
this.exception = e;
+ TraceUtil.setError(span, e);
if (e.getCause() instanceof SQLException) {
throw (SQLException) e.getCause();
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
index d3df4647095..908f3bf3246 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
@@ -42,6 +42,8 @@
import static org.apache.phoenix.monitoring.MetricType.UPSERT_SQL_COUNTER;
import static org.apache.phoenix.monitoring.MetricType.UPSERT_SQL_QUERY_TIME;
import static org.apache.phoenix.monitoring.MetricType.UPSERT_SUCCESS_SQL_COUNTER;
+import static org.apache.phoenix.trace.PhoenixSemanticAttributes.DB_STATEMENT;
+
import java.io.File;
import java.io.IOException;
@@ -207,7 +209,7 @@
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PLong;
import org.apache.phoenix.schema.types.PVarchar;
-import org.apache.phoenix.trace.util.Tracing;
+import org.apache.phoenix.trace.TraceUtil;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.CursorUtil;
import org.apache.phoenix.util.PhoenixKeyValueUtil;
@@ -218,16 +220,22 @@
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.QueryUtil;
import org.apache.phoenix.util.SQLCloseable;
+import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.util.ServerUtil;
import org.apache.phoenix.util.ParseNodeUtil.RewriteResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Scope;
+
import org.apache.phoenix.thirdparty.com.google.common.base.Throwables;
import org.apache.phoenix.thirdparty.com.google.common.collect.ListMultimap;
import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
import org.apache.phoenix.thirdparty.com.google.common.math.IntMath;
import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
+
/**
*
* JDBC Statement implementation of Phoenix.
@@ -279,6 +287,7 @@ public String toString() {
private static final String TABLE_UNKNOWN = "";
private QueryPlan lastQueryPlan;
private PhoenixResultSet lastResultSet;
+ private Span lastQuerySpan;
private int lastUpdateCount = NO_UPDATE;
private String lastUpdateTable = TABLE_UNKNOWN;
@@ -332,6 +341,22 @@ protected PhoenixResultSet executeQuery(final CompilableStatement stmt, final Qu
return executeQuery(stmt, true, queryLogger, noCommit);
}
+ private String getSpanName(String statementType, String tableSchema, String tableName) {
+ if(tableName != null) {
+ return statementType + " " + SchemaUtil.getQualifiedPhoenixTableName(tableSchema, tableName);
+ }
+ String dbName;
+ try {
+ dbName = connection.getSchema();
+ if (dbName != null) {
+ return statementType + " " + dbName;
+ }
+ } catch (SQLException e) {
+ //fall through
+ }
+ return statementType;
+ }
+
private PhoenixResultSet executeQuery(final CompilableStatement stmt,
final boolean doRetryOnMetaNotFoundError, final QueryLogger queryLogger, final boolean noCommit) throws SQLException {
GLOBAL_SELECT_SQL_COUNTER.increment();
@@ -344,74 +369,96 @@ private PhoenixResultSet executeQuery(final CompilableStatement stmt,
boolean success = false;
boolean pointLookup = false;
String tableName = null;
- clearResultSet();
PhoenixResultSet rs = null;
- try {
- PhoenixConnection conn = getConnection();
- conn.checkOpen();
-
- if (conn.getQueryServices().isUpgradeRequired() && !conn
- .isRunningUpgrade()
- && stmt.getOperation() != Operation.UPGRADE) {
- throw new UpgradeRequiredException();
- }
- QueryPlan
+ clearResultSet();
+ try (Scope connScope = connection.makeCurrent()) {
+ lastQuerySpan = TraceUtil.createSpan(connection, getSpanName(stmt.getKeyword(), connection.getSchema(), null));
+ lastQuerySpan.setAttribute(DB_STATEMENT, stmt.toString());
+ try (Scope ignored = lastQuerySpan.makeCurrent()) {
+ PhoenixConnection conn = getConnection();
+ conn.checkOpen();
+
+ if (conn.getQueryServices().isUpgradeRequired() && !conn
+ .isRunningUpgrade()
+ && stmt.getOperation() != Operation.UPGRADE) {
+ throw new UpgradeRequiredException();
+ }
+
+ QueryPlan plan;
+ Span compileSpan = TraceUtil.createSpan(connection, "Compiling and optimizing plan for " + stmt);
+ try (Scope compileScope = compileSpan.makeCurrent()) {
plan =
- stmt.compilePlan(PhoenixStatement.this,
- Sequence.ValueOp.VALIDATE_SEQUENCE);
- // Send mutations to hbase, so they are visible to subsequent reads.
- // Use original plan for data table so that data and immutable indexes will be sent
- // TODO: for joins, we need to iterate through all tables, but we need the original table,
- // not the projected table, so plan.getContext().getResolver().getTables() won't work.
- if (plan.getTableRef() != null
- && plan.getTableRef().getTable() != null && !Strings
- .isNullOrEmpty(
- plan.getTableRef().getTable().getPhysicalName()
- .toString())) {
- tableName = plan.getTableRef().getTable().getPhysicalName()
- .toString();
- }
- if (plan.getContext().getScanRanges().isPointLookup()) {
- pointLookup = true;
- }
- Iterator tableRefs = plan.getSourceRefs().iterator();
- connection.getMutationState().sendUncommitted(tableRefs);
- plan =
- connection.getQueryServices().getOptimizer()
- .optimize(PhoenixStatement.this, plan);
- // this will create its own trace internally, so we don't wrap this
- // whole thing in tracing
- ResultIterator resultIterator = plan.iterator();
- if (LOGGER.isDebugEnabled()) {
- String explainPlan = QueryUtil.getExplainPlan(resultIterator);
- LOGGER.debug(LogUtil.addCustomAnnotations(
- "Explain plan: " + explainPlan, connection));
- }
- StatementContext context = plan.getContext();
- context.setQueryLogger(queryLogger);
- if (queryLogger.isDebugEnabled()) {
- queryLogger.log(QueryLogInfo.EXPLAIN_PLAN_I,
- QueryUtil.getExplainPlan(resultIterator));
- queryLogger.log(QueryLogInfo.GLOBAL_SCAN_DETAILS_I,
- context.getScan() != null ?
- context.getScan().toString() :
- null);
- }
- context.getOverallQueryMetrics().startQuery();
- rs =
- newResultSet(resultIterator, plan.getProjector(),
- plan.getContext());
- // newResultset sets lastResultset
- setLastQueryPlan(plan);
- setLastUpdateCount(NO_UPDATE);
- setLastUpdateTable(tableName == null ? TABLE_UNKNOWN : tableName);
- setLastUpdateOperation(stmt.getOperation());
- // If transactional, this will move the read pointer forward
- if (connection.getAutoCommit() && !noCommit) {
- connection.commit();
+ stmt.compilePlan(PhoenixStatement.this,
+ Sequence.ValueOp.VALIDATE_SEQUENCE);
+ compileSpan.addEvent("plan compiled. Optimizing.");
+ plan =
+ connection.getQueryServices().getOptimizer()
+ .optimize(PhoenixStatement.this, plan);
+ compileSpan.setStatus(StatusCode.OK);
+ } catch (Exception e) {
+ TraceUtil.setError(compileSpan, e);
+ throw e;
+ } finally {
+ compileSpan.end();
+ }
+ // Send mutations to hbase, so they are visible to subsequent reads.
+ // Use original plan for data table so that data and immutable indexes will be sent
+ // TODO: for joins, we need to iterate through all tables, but we need the original table,
+ // not the projected table, so plan.getContext().getResolver().getTables() won't work.
+ if (plan.getTableRef() != null
+ && plan.getTableRef().getTable() != null && !Strings
+ .isNullOrEmpty(
+ plan.getTableRef().getTable().getPhysicalName()
+ .toString())) {
+ tableName = plan.getTableRef().getTable().getPhysicalName()
+ .toString();
+ // TODO This may not work non-select statements
+ lastQuerySpan.updateName(getSpanName("SELECT",
+ plan.getTableRef().getTable().getSchemaName().getString(),
+ plan.getTableRef().getTable().getTableName().getString()));
+ }
+ if (plan.getContext().getScanRanges().isPointLookup()) {
+ pointLookup = true;
+ }
+ Iterator tableRefs = plan.getSourceRefs().iterator();
+ connection.getMutationState().sendUncommitted(tableRefs);
+ // this will create its own trace internally, so we don't wrap this
+ // whole thing in tracing
+ ResultIterator resultIterator = plan.iterator();
+ if (LOGGER.isDebugEnabled()) {
+ String explainPlan = QueryUtil.getExplainPlan(resultIterator);
+ LOGGER.debug(LogUtil.addCustomAnnotations(
+ "Explain plan: " + explainPlan, connection));
+ }
+ StatementContext context = plan.getContext();
+ context.setQueryLogger(queryLogger);
+ if (queryLogger.isDebugEnabled()) {
+ queryLogger.log(QueryLogInfo.EXPLAIN_PLAN_I,
+ QueryUtil.getExplainPlan(resultIterator));
+ queryLogger.log(QueryLogInfo.GLOBAL_SCAN_DETAILS_I,
+ context.getScan() != null ?
+ context.getScan().toString() :
+ null);
+ }
+
+ context.getOverallQueryMetrics().startQuery();
+ rs =
+ newResultSet(resultIterator, plan.getProjector(),
+ plan.getContext());
+ // newResultset sets lastResultset
+ setLastQueryPlan(plan);
+ setLastUpdateCount(NO_UPDATE);
+ setLastUpdateTable(tableName == null ? TABLE_UNKNOWN : tableName);
+ setLastUpdateOperation(stmt.getOperation());
+ // If transactional, this will move the read pointer forward
+ if (connection.getAutoCommit() && !noCommit) {
+ connection.commit();
+ }
+
+ connection.incrementStatementExecutionCounter();
+ success = true;
+ lastQuerySpan.setStatus(StatusCode.OK);
}
- connection.incrementStatementExecutionCounter();
- success = true;
}
//Force update cache and retry if meta not found error occurs
catch (MetaDataEntityNotFoundException e) {
@@ -420,17 +467,34 @@ private PhoenixResultSet executeQuery(final CompilableStatement stmt,
LOGGER.debug("Reloading table {} data from server",
e.getTableName());
}
- if (new MetaDataClient(connection)
- .updateCache(connection.getTenantId(),
+ boolean wasUpdated;
+ try (Scope ignored = lastQuerySpan.makeCurrent()) {
+ lastQuerySpan.addEvent("Trying to reload table " + e.getTableName() + " data from server");
+ wasUpdated = new MetaDataClient(connection)
+ .updateCache(connection.getTenantId(),
e.getSchemaName(), e.getTableName(), true)
- .wasUpdated()) {
- //TODO we can log retry count and error for debugging in LOG table
+ .wasUpdated();
+ if (wasUpdated) {
+ lastQuerySpan.addEvent("Reloading table data was successful");
+ lastQuerySpan.addEvent("Attempting to execute the query again");
+ lastQuerySpan.setStatus(StatusCode.OK);
+ } else {
+ lastQuerySpan.addEvent("Reloading table data was not successful");
+ TraceUtil.setError(lastQuerySpan, e);
+ lastQuerySpan.end();
+ }
+ }
+ if (wasUpdated) {
+ // TODO we can log retry count and error for debugging in LOG table
+ // This will run an new span
+ // TODO could maybe link the retry span to the failed one ?
return executeQuery(stmt, false, queryLogger, noCommit);
}
}
throw e;
} catch (RuntimeException e) {
-
+ TraceUtil.setError(lastQuerySpan, e);
+ lastQuerySpan.end();
// FIXME: Expression.evaluate does not throw SQLException
// so this will unwrap throws from that.
if (e.getCause() instanceof SQLException) {
@@ -516,11 +580,11 @@ public String getTargetForAudit(CompilableStatement stmt) {
}
- protected int executeMutation(final CompilableStatement stmt, final AuditQueryLogger queryLogger) throws SQLException {
- return executeMutation(stmt, true, queryLogger);
+ protected int executeMutation(final CompilableStatement stmt, final AuditQueryLogger queryLogger, String originalSQL) throws SQLException {
+ return executeMutation(stmt, true, queryLogger, originalSQL);
}
- private int executeMutation(final CompilableStatement stmt, final boolean doRetryOnMetaNotFoundError, final AuditQueryLogger queryLogger) throws SQLException {
+ private int executeMutation(final CompilableStatement stmt, final boolean doRetryOnMetaNotFoundError, final AuditQueryLogger queryLogger, String originalSQL) throws SQLException {
if (connection.isReadOnly()) {
throw new SQLExceptionInfo.Builder(
SQLExceptionCode.READ_ONLY_CONNECTION).
@@ -528,137 +592,155 @@ private int executeMutation(final CompilableStatement stmt, final boolean doRetr
}
GLOBAL_MUTATION_SQL_COUNTER.increment();
try {
- return CallRunner
- .run(
- new CallRunner.CallableThrowable() {
- @Override
- public Integer call() throws SQLException {
- boolean success = false;
- String tableName = null;
- boolean isUpsert = false;
- boolean isAtomicUpsert = false;
- boolean isDelete = false;
- MutationState state = null;
- MutationPlan plan = null;
- final long startExecuteMutationTime = EnvironmentEdgeManager.currentTimeMillis();
- clearResultSet();
- try {
- PhoenixConnection conn = getConnection();
- if (conn.getQueryServices().isUpgradeRequired() && !conn.isRunningUpgrade()
- && stmt.getOperation() != Operation.UPGRADE) {
- throw new UpgradeRequiredException();
- }
- state = connection.getMutationState();
- plan = stmt.compilePlan(PhoenixStatement.this, Sequence.ValueOp.VALIDATE_SEQUENCE);
- isUpsert = stmt instanceof ExecutableUpsertStatement;
- isDelete = stmt instanceof ExecutableDeleteStatement;
- isAtomicUpsert = isUpsert && ((ExecutableUpsertStatement)stmt).getOnDupKeyPairs() != null;
- if (plan.getTargetRef() != null && plan.getTargetRef().getTable() != null) {
- if (!Strings.isNullOrEmpty(plan.getTargetRef().getTable().getPhysicalName().toString())) {
- tableName = plan.getTargetRef().getTable().getPhysicalName().toString();
- }
- if (plan.getTargetRef().getTable().isTransactional()) {
- state.startTransaction(plan.getTargetRef().getTable().getTransactionProvider());
+ return CallRunner.run(
+ new CallRunner.CallableThrowable() {
+ @Override
+ public Integer call() throws SQLException {
+ boolean success = false;
+ String tableName = null;
+ boolean isUpsert = false;
+ boolean isAtomicUpsert = false;
+ boolean isDelete = false;
+ MutationState state = null;
+ MutationPlan plan = null;
+ final long startExecuteMutationTime = EnvironmentEdgeManager.currentTimeMillis();
+ clearResultSet();
+ // TODO for queries we use re-constructed SQLs. We don't have code to do that
+ // for DLMs, so we just the original
+ isUpsert = stmt instanceof ExecutableUpsertStatement;
+ isDelete = stmt instanceof ExecutableDeleteStatement;
+ isAtomicUpsert = isUpsert && ((ExecutableUpsertStatement)stmt).getOnDupKeyPairs() != null;
+
+ try (Scope connScope = connection.makeCurrent()) {
+ Span span = TraceUtil.createSpan(connection, getSpanName(stmt.getKeyword(), connection.getSchema(), null));
+ span.setAttribute(DB_STATEMENT, originalSQL);
+ try (Scope scope = span.makeCurrent()) {
+ PhoenixConnection conn = getConnection();
+ if (conn.getQueryServices().isUpgradeRequired() && !conn.isRunningUpgrade()
+ && stmt.getOperation() != Operation.UPGRADE) {
+ throw new UpgradeRequiredException();
+ }
+ state = connection.getMutationState();
+ plan = stmt.compilePlan(PhoenixStatement.this, Sequence.ValueOp.VALIDATE_SEQUENCE);
+ if (plan.getTargetRef() != null && plan.getTargetRef().getTable() != null) {
+ if (!Strings.isNullOrEmpty(plan.getTargetRef().getTable().getPhysicalName().toString())) {
+ tableName = plan.getTargetRef().getTable().getPhysicalName().toString();
+ span.updateName(getSpanName(stmt.getKeyword(),
+ plan.getTargetRef().getTable().getSchemaName().getString(),
+ plan.getTargetRef().getTable().getTableName().getString()));
}
+ if (plan.getTargetRef().getTable().isTransactional()) {
+ state.startTransaction(plan.getTargetRef().getTable().getTransactionProvider());
}
- Iterator tableRefs = plan.getSourceRefs().iterator();
- state.sendUncommitted(tableRefs);
- state.checkpointIfNeccessary(plan);
- checkIfDDLStatementandMutationState(stmt, state);
- MutationState lastState = plan.execute();
- state.join(lastState);
- if (connection.getAutoCommit()) {
- connection.commit();
- }
- setLastQueryPlan(null);
- // Unfortunately, JDBC uses an int for update count, so we
- // just max out at Integer.MAX_VALUE
- int lastUpdateCount = (int) Math.min(Integer.MAX_VALUE, lastState.getUpdateCount());
- setLastUpdateCount(lastUpdateCount);
- setLastUpdateOperation(stmt.getOperation());
- setLastUpdateTable(tableName == null ? TABLE_UNKNOWN : tableName);
- connection.incrementStatementExecutionCounter();
- if (queryLogger.isAuditLoggingEnabled()) {
- queryLogger.log(QueryLogInfo.TABLE_NAME_I, getTargetForAudit(stmt));
- queryLogger.log(QueryLogInfo.QUERY_STATUS_I, QueryStatus.COMPLETED.toString());
- queryLogger.log(QueryLogInfo.NO_OF_RESULTS_ITERATED_I, lastUpdateCount);
- queryLogger.syncAudit();
- }
-
- success = true;
- return lastUpdateCount;
}
- //Force update cache and retry if meta not found error occurs
- catch (MetaDataEntityNotFoundException e) {
- if (doRetryOnMetaNotFoundError && e.getTableName() != null) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Reloading table {} data from server", e.getTableName());
- }
+ Iterator tableRefs = plan.getSourceRefs().iterator();
+ state.sendUncommitted(tableRefs);
+ state.checkpointIfNeccessary(plan);
+ checkIfDDLStatementandMutationState(stmt, state);
+ MutationState lastState = plan.execute();
+ state.join(lastState);
+ if (connection.getAutoCommit()) {
+ connection.commit();
+ }
+ setLastQueryPlan(null);
+ // Unfortunately, JDBC uses an int for update count, so we
+ // just max out at Integer.MAX_VALUE
+ int lastUpdateCount = (int) Math.min(Integer.MAX_VALUE, lastState.getUpdateCount());
+ setLastUpdateCount(lastUpdateCount);
+ setLastUpdateOperation(stmt.getOperation());
+ setLastUpdateTable(tableName == null ? TABLE_UNKNOWN : tableName);
+ connection.incrementStatementExecutionCounter();
+ if (queryLogger.isAuditLoggingEnabled()) {
+ queryLogger.log(QueryLogInfo.TABLE_NAME_I, getTargetForAudit(stmt));
+ queryLogger.log(QueryLogInfo.QUERY_STATUS_I, QueryStatus.COMPLETED.toString());
+ queryLogger.log(QueryLogInfo.NO_OF_RESULTS_ITERATED_I, lastUpdateCount);
+ queryLogger.syncAudit();
+ }
+
+ success = true;
+ span.setStatus(StatusCode.OK);
+ return lastUpdateCount;
+ }
+ //Force update cache and retry if meta not found error occurs
+ catch (MetaDataEntityNotFoundException e) {
+ TraceUtil.setError(span, e);
+ if (doRetryOnMetaNotFoundError && e.getTableName() != null) {
+ // The inner executeMutation is going to get its own Span
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Reloading table {} data from server", e.getTableName());
+ }
+ try (Scope ignored = span.makeCurrent()) {
+ span.addEvent("Reloading table " + e.getTableName() + " data from server");
if (new MetaDataClient(connection).updateCache(connection.getTenantId(),
e.getSchemaName(), e.getTableName(), true).wasUpdated()) {
- return executeMutation(stmt, false, queryLogger);
+ return executeMutation(stmt, false, queryLogger, originalSQL);
}
}
- throw e;
- }catch (RuntimeException e) {
- // FIXME: Expression.evaluate does not throw SQLException
- // so this will unwrap throws from that.
- if (e.getCause() instanceof SQLException) {
- throw (SQLException) e.getCause();
- }
- throw e;
- } finally {
- // Regardless of whether the mutation was successfully handled or not,
- // update the time spent so far. If needed, we can separate out the
- // success times and failure times.
- if (tableName != null) {
- // Counts for both ddl and dml
- TableMetricsManager.updateMetricsMethod(tableName,
- MUTATION_SQL_COUNTER, 1);
- // Only count dml operations
- if (isUpsert || isDelete) {
- long executeMutationTimeSpent =
- EnvironmentEdgeManager.currentTimeMillis() - startExecuteMutationTime;
-
+ }
+ throw e;
+ } catch (RuntimeException e) {
+ TraceUtil.setError(span, e);
+ // FIXME: Expression.evaluate does not throw SQLException
+ // so this will unwrap throws from that.
+ if (e.getCause() instanceof SQLException) {
+ throw (SQLException) e.getCause();
+ }
+ throw e;
+ } catch (Throwable e) {
+ TraceUtil.setError(span, e);
+ throw e;
+ } finally {
+ // Regardless of whether the mutation was successfully handled or not,
+ // update the time spent so far. If needed, we can separate out the
+ // success times and failure times.
+ if (tableName != null) {
+ // Counts for both ddl and dml
+ TableMetricsManager.updateMetricsMethod(tableName,
+ MUTATION_SQL_COUNTER, 1);
+ // Only count dml operations
+ if (isUpsert || isDelete) {
+ long executeMutationTimeSpent =
+ EnvironmentEdgeManager.currentTimeMillis() - startExecuteMutationTime;
+
+ TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
+ UPSERT_SQL_COUNTER : DELETE_SQL_COUNTER, 1);
+ TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
+ UPSERT_SQL_QUERY_TIME : DELETE_SQL_QUERY_TIME, executeMutationTimeSpent);
+ if (isAtomicUpsert) {
+ TableMetricsManager.updateMetricsMethod(tableName,
+ ATOMIC_UPSERT_SQL_COUNTER, 1);
+ TableMetricsManager.updateMetricsMethod(tableName,
+ ATOMIC_UPSERT_SQL_QUERY_TIME, executeMutationTimeSpent);
+ }
+
+ if (success) {
TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
- UPSERT_SQL_COUNTER : DELETE_SQL_COUNTER, 1);
+ UPSERT_SUCCESS_SQL_COUNTER : DELETE_SUCCESS_SQL_COUNTER, 1);
+ } else {
TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
- UPSERT_SQL_QUERY_TIME : DELETE_SQL_QUERY_TIME, executeMutationTimeSpent);
- if (isAtomicUpsert) {
- TableMetricsManager.updateMetricsMethod(tableName,
- ATOMIC_UPSERT_SQL_COUNTER, 1);
- TableMetricsManager.updateMetricsMethod(tableName,
- ATOMIC_UPSERT_SQL_QUERY_TIME, executeMutationTimeSpent);
- }
-
- if (success) {
- TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
- UPSERT_SUCCESS_SQL_COUNTER : DELETE_SUCCESS_SQL_COUNTER, 1);
- } else {
- TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
- UPSERT_FAILED_SQL_COUNTER : DELETE_FAILED_SQL_COUNTER, 1);
- //Failures are updated for executeMutation phase and for autocommit=true case here.
- TableMetricsManager.updateMetricsMethod(tableName, isUpsert ? UPSERT_AGGREGATE_FAILURE_SQL_COUNTER:
- DELETE_AGGREGATE_FAILURE_SQL_COUNTER, 1);
- }
- if (plan instanceof DeleteCompiler.ServerSelectDeleteMutationPlan
- || plan instanceof UpsertCompiler.ServerUpsertSelectMutationPlan) {
- TableMetricsManager.updateLatencyHistogramForMutations(
- tableName, executeMutationTimeSpent, false);
- // We won't have size histograms for delete mutations when auto commit is set to true and
- // if plan is of ServerSelectDeleteMutationPlan or ServerUpsertSelectMutationPlan
- // since the update happens on server.
- } else {
- state.addExecuteMutationTime(
- executeMutationTimeSpent, tableName);
- }
+ UPSERT_FAILED_SQL_COUNTER : DELETE_FAILED_SQL_COUNTER, 1);
+ //Failures are updated for executeMutation phase and for autocommit=true case here.
+ TableMetricsManager.updateMetricsMethod(tableName, isUpsert ? UPSERT_AGGREGATE_FAILURE_SQL_COUNTER:
+ DELETE_AGGREGATE_FAILURE_SQL_COUNTER, 1);
+ }
+ if (plan instanceof DeleteCompiler.ServerSelectDeleteMutationPlan
+ || plan instanceof UpsertCompiler.ServerUpsertSelectMutationPlan) {
+ TableMetricsManager.updateLatencyHistogramForMutations(
+ tableName, executeMutationTimeSpent, false);
+ // We won't have size histograms for delete mutations when auto commit is set to true and
+ // if plan is of ServerSelectDeleteMutationPlan or ServerUpsertSelectMutationPlan
+ // since the update happens on server.
+ } else {
+ state.addExecuteMutationTime(
+ executeMutationTimeSpent, tableName);
}
}
-
}
+ span.end();
}
- }, PhoenixContextExecutor.inContext(),
- Tracing.withTracing(connection, this.toString()));
+ }
+ }
+ }, PhoenixContextExecutor.inContext());
} catch (Exception e) {
if (queryLogger.isAuditLoggingEnabled()) {
queryLogger.log(QueryLogInfo.TABLE_NAME_I, getTargetForAudit(stmt));
@@ -2093,7 +2175,7 @@ public void close() throws SQLException {
// From the ResultSet javadoc:
// A ResultSet object is automatically closed when the Statement object that generated it is
// closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
- private void clearResultSet() throws SQLException {
+ void clearResultSet() throws SQLException {
if (lastResultSet != null) {
try {
lastResultSet.close();
@@ -2231,7 +2313,7 @@ public int executeUpdate(String sql) throws SQLException {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.EXECUTE_UPDATE_WITH_NON_EMPTY_BATCH)
.build().buildException();
}
- int updateCount = executeMutation(stmt, createAuditQueryLogger(stmt, sql));
+ int updateCount = executeMutation(stmt, createAuditQueryLogger(stmt, sql), sql);
flushIfNecessary();
return updateCount;
}
@@ -2250,7 +2332,7 @@ public boolean execute(String sql) throws SQLException {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.EXECUTE_UPDATE_WITH_NON_EMPTY_BATCH)
.build().buildException();
}
- executeMutation(stmt, createAuditQueryLogger(stmt, sql));
+ executeMutation(stmt, createAuditQueryLogger(stmt, sql), sql);
flushIfNecessary();
return false;
}
@@ -2498,12 +2580,16 @@ public boolean isCloseOnCompletion() throws SQLException {
return closeOnCompletion;
}
- private PhoenixResultSet getLastResultSet() {
+ PhoenixResultSet getLastResultSet() {
return lastResultSet;
}
- void setLastResultSet(PhoenixResultSet lastResultSet) {
+ void setLastResultSet(PhoenixResultSet lastResultSet) throws SQLException {
+ this.clearResultSet();
this.lastResultSet = lastResultSet;
+ if (lastQuerySpan == null) {
+ lastQuerySpan = TraceUtil.createSpan(connection, "Query Span for synthetic ResultSet");
+ }
}
private int getLastUpdateCount() {
@@ -2518,6 +2604,10 @@ private String getLastUpdateTable() {
return lastUpdateTable;
}
+ Span getLastQuerySpan() {
+ return lastQuerySpan;
+ }
+
private void setLastUpdateTable(String lastUpdateTable) {
if (!Strings.isNullOrEmpty(lastUpdateTable)) {
this.lastUpdateTable = lastUpdateTable;
@@ -2547,7 +2637,6 @@ private QueryPlan getLastQueryPlan() {
private void setLastQueryPlan(QueryPlan lastQueryPlan) {
this.lastQueryPlan = lastQueryPlan;
-
}
private void updateActivityOnConnection(ActivityLogInfo item, String value) {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/AddJarsStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/AddJarsStatement.java
index b1eeea6e54c..a56dd4c2a0d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/AddJarsStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/AddJarsStatement.java
@@ -35,4 +35,9 @@ public int getBindCount() {
public List getJarPaths() {
return jarPaths;
}
+
+ @Override
+ public String getKeyword() {
+ return "ADD JARS";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java
index 32a3c042c5a..2f6b3c0cd0c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java
@@ -74,4 +74,9 @@ public boolean isRebuildAll() {
public ListMultimap> getProps() { return props; }
public PTableType getTableType(){ return tableType; }
+
+ @Override
+ public String getKeyword() {
+ return "ALTER INDEX";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterSessionStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterSessionStatement.java
index 5d944dfe8a5..04bb5820713 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterSessionStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterSessionStatement.java
@@ -35,4 +35,9 @@ public int getBindCount() {
public Map getProps(){
return props;
}
+
+ @Override
+ public String getKeyword() {
+ return "ALTER SESSION";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterTableStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterTableStatement.java
index a3340119439..5d56c68c092 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterTableStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterTableStatement.java
@@ -30,4 +30,8 @@ public abstract class AlterTableStatement extends SingleTableStatement {
public PTableType getTableType() {
return tableType;
}
+
+ public String getKeyword() {
+ return "ALTER TABLE";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/BindableStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/BindableStatement.java
index 6594f49bb3c..b7211d56128 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/BindableStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/BindableStatement.java
@@ -23,4 +23,5 @@
public interface BindableStatement {
public int getBindCount();
public Operation getOperation();
+ public String getKeyword();
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ChangePermsStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ChangePermsStatement.java
index b49183d3a3b..103c93ea7bd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ChangePermsStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ChangePermsStatement.java
@@ -100,4 +100,9 @@ public int getBindCount() {
public PhoenixStatement.Operation getOperation() {
return PhoenixStatement.Operation.ADMIN;
}
+
+ @Override
+ public String getKeyword() {
+ return isGrantStatement ? "GRANT" : "REVOKE";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/CloseStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/CloseStatement.java
index 5d7af346472..4dc5ac05de7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/CloseStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/CloseStatement.java
@@ -37,4 +37,9 @@ public int getBindCount(){
public Operation getOperation(){
return Operation.UPSERT;
}
+
+ @Override
+ public String getKeyword() {
+ return "CLOSE CURSOR";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateFunctionStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateFunctionStatement.java
index 863783bd67f..bc21ea052d3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateFunctionStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateFunctionStatement.java
@@ -44,4 +44,9 @@ public boolean isTemporary() {
public boolean isReplace() {
return isReplace;
}
+
+ @Override
+ public String getKeyword() {
+ return "CREATE FUNCTION";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateIndexStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateIndexStatement.java
index de15ac88ea6..236cc571648 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateIndexStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateIndexStatement.java
@@ -108,7 +108,13 @@ public boolean isAsync() {
public Map getUdfParseNodes() {
return udfParseNodes;
}
+
public ParseNode getWhere() {
return where;
}
+
+ @Override
+ public String getKeyword() {
+ return "CREATE INDEX";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java
index f5ab3f6bc3a..2909321aca8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java
@@ -41,4 +41,8 @@ public boolean isIfNotExists() {
return ifNotExists;
}
+ @Override
+ public String getKeyword() {
+ return "CREATE SCHEMA";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSequenceStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSequenceStatement.java
index 2e0c943629b..a2f84e3997f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSequenceStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSequenceStatement.java
@@ -88,4 +88,9 @@ public ParseNode getStartWith() {
public boolean ifNotExists() {
return ifNotExists;
}
+
+ @Override
+ public String getKeyword() {
+ return "CREATE SEQUENCE";
+ }
}
\ No newline at end of file
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateTableStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateTableStatement.java
index 37376c985eb..147a0a07b23 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateTableStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateTableStatement.java
@@ -165,4 +165,9 @@ public Map getFamilyCQCounters() {
public boolean isNoVerify() {
return noVerify;
}
+
+ @Override
+ public String getKeyword() {
+ return "CREATE TABLE";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DMLStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DMLStatement.java
index 3b9bd97e1a9..99e23bd609d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DMLStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DMLStatement.java
@@ -19,7 +19,7 @@
import java.util.Map;
-public class DMLStatement extends SingleTableStatement {
+public abstract class DMLStatement extends SingleTableStatement {
private final Map udfParseNodes;
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeclareCursorStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeclareCursorStatement.java
index 68129ecac05..acb5f979a09 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeclareCursorStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeclareCursorStatement.java
@@ -57,4 +57,9 @@ public int getBindCount(){
public Operation getOperation(){
return Operation.UPSERT;
}
+
+ @Override
+ public String getKeyword() {
+ return "DECLARE CURSOR";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteJarStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteJarStatement.java
index a7438ef56aa..cea48d84d7b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteJarStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteJarStatement.java
@@ -33,4 +33,9 @@ public int getBindCount() {
public LiteralParseNode getJarPath() {
return jarPath;
}
+
+ @Override
+ public String getKeyword() {
+ return "DELETE JAR";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java
index 331bee4133e..a2ebd222d46 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java
@@ -82,4 +82,8 @@ public Double getTableSamplingRate(){
throw new UnsupportedOperationException("Table sampling is not allowd for Deletion");
}
+ @Override
+ public String getKeyword() {
+ return "DELETE";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropFunctionStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropFunctionStatement.java
index a959eb7da18..d0f98e0baa5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropFunctionStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropFunctionStatement.java
@@ -38,4 +38,9 @@ public String getFunctionName() {
public boolean ifExists() {
return ifExists;
}
+
+ @Override
+ public String getKeyword() {
+ return "DROP FUNCTION";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropIndexStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropIndexStatement.java
index 288d081c03c..51fcd6ca3d0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropIndexStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropIndexStatement.java
@@ -51,4 +51,10 @@ public boolean ifExists() {
public Operation getOperation() {
return Operation.DELETE;
}
+
+ @Override
+ public String getKeyword() {
+ return "DROP INDEX";
+ }
}
+
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java
index 5d03a787352..11d2a126adb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java
@@ -52,4 +52,8 @@ public Operation getOperation() {
return Operation.DELETE;
}
+ @Override
+ public String getKeyword() {
+ return "DROP SCHEMA";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSequenceStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSequenceStatement.java
index c4093a1a0e4..a49670754f6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSequenceStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSequenceStatement.java
@@ -43,9 +43,14 @@ public TableName getSequenceName() {
public boolean ifExists() {
return ifExists;
}
-
+
@Override
public Operation getOperation() {
return Operation.DELETE;
}
+
+ @Override
+ public String getKeyword() {
+ return "DROP SEQUENCE";
+ }
}
\ No newline at end of file
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropTableStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropTableStatement.java
index c334a819b9e..a00928b9947 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropTableStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropTableStatement.java
@@ -65,4 +65,9 @@ public Operation getOperation() {
public boolean getSkipAddingParentColumns() {
return skipAddingParentColumns;
}
+
+ @Override
+ public String getKeyword() {
+ return "DROP TABLE";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java
index 29edf8f329b..fbfbac94ce9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java
@@ -31,4 +31,8 @@ public Operation getOperation() {
return Operation.UPGRADE;
}
+ @Override
+ public String getKeyword() {
+ return "EXECUTE UPGRADE";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java
index 3b28ca5c0d5..3a9db78f2e8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java
@@ -45,4 +45,9 @@ public Operation getOperation() {
public ExplainType getExplainType() {
return explainType;
}
+
+ @Override
+ public String getKeyword() {
+ return "EXPLAIN";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/FetchStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/FetchStatement.java
index 08e97249633..e56ec95caf9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/FetchStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FetchStatement.java
@@ -49,4 +49,9 @@ public Operation getOperation(){
public int getFetchSize(){
return fetchSize;
}
+
+ @Override
+ public String getKeyword() {
+ return "FETCH";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ListJarsStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ListJarsStatement.java
index e9821fbed83..4736f6dfa5b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ListJarsStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ListJarsStatement.java
@@ -31,4 +31,8 @@ public Operation getOperation() {
return Operation.QUERY;
}
+ @Override
+ public String getKeyword() {
+ return "LIST JARS";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/OpenStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/OpenStatement.java
index ad905b0d12e..215dcfd83a9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/OpenStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/OpenStatement.java
@@ -37,4 +37,9 @@ public int getBindCount(){
public Operation getOperation(){
return Operation.UPSERT;
}
+
+ @Override
+ public String getKeyword() {
+ return "OPEN CURSOR";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java
index 8f937a93456..a585ff1fc3e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java
@@ -371,4 +371,8 @@ public OffsetNode getOffset() {
return offset;
}
+ @Override
+ public String getKeyword() {
+ return "SELECT";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowCreateTable.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowCreateTable.java
index 4fe77a7b4cd..aa8b66bf2bf 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowCreateTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowCreateTable.java
@@ -35,4 +35,9 @@ public PhoenixStatement.Operation getOperation() {
}
public ShowCreateTable() {}
+
+ @Override
+ public String getKeyword() {
+ return "SHOW CREATE TABLE";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowSchemasStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowSchemasStatement.java
index 8e95e0e0393..56847bc0a01 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowSchemasStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowSchemasStatement.java
@@ -67,4 +67,9 @@ public boolean equals(Object other) {
public int hashCode() {
return Objects.hashCode(schemaPattern);
}
+
+ @Override
+ public String getKeyword() {
+ return "SHOW SCHEMAS";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowStatement.java
index d4ab7a487e4..6802cafc9d4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowStatement.java
@@ -23,7 +23,7 @@
/**
* Parent class for all SHOW statements. SHOW SCHEMAS, SHOW TABLES etc.
*/
-public class ShowStatement implements BindableStatement {
+public abstract class ShowStatement implements BindableStatement {
@Override
public int getBindCount() {
return 0;
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowTablesStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowTablesStatement.java
index 0371a452dd3..d3af0a080b9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowTablesStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ShowTablesStatement.java
@@ -89,4 +89,9 @@ public boolean equals(Object other) {
public int hashCode() {
return Objects.hash(targetSchema, dbPattern);
}
+
+ @Override
+ public String getKeyword() {
+ return "SHOW TABLES";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraceStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraceStatement.java
index 301fa56d3a9..51a8c15781e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraceStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraceStatement.java
@@ -46,4 +46,9 @@ public boolean isTraceOn() {
public double getSamplingRate() {
return samplingRate;
}
+
+ @Override
+ public String getKeyword() {
+ return "TRACE " + (traceOn ? "ON" : "OFF");
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
index 10f0b2fb4e3..12f61b2606b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
@@ -53,4 +53,9 @@ public boolean updateAll() {
public Map getProps() {
return props;
};
+
+ @Override
+ public String getKeyword() {
+ return "UPDATE STATISTICS";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java
index fca746320ba..3e2e80379d7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java
@@ -60,4 +60,9 @@ public HintNode getHint() {
public List> getOnDupKeyPairs() {
return onDupKeyPairs;
}
+
+ @Override
+ public String getKeyword() {
+ return "UPSERT";
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java
index abba30963f5..cada83512ba 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java
@@ -35,4 +35,8 @@ public String getSchemaName() {
return schemaName;
}
+ @Override
+ public String getKeyword() {
+ return "USE SCHEMA";
+ }
}
\ No newline at end of file
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
index e477f28cf49..ec649474924 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
@@ -195,7 +195,6 @@ public interface QueryServices extends SQLCloseable {
public static final String TRACING_FREQ_ATTRIB = "phoenix.trace.frequency";
public static final String TRACING_PAGE_SIZE_ATTRIB = "phoenix.trace.read.pagesize";
public static final String TRACING_PROBABILITY_THRESHOLD_ATTRIB = "phoenix.trace.probability.threshold";
- public static final String TRACING_STATS_TABLE_NAME_ATTRIB = "phoenix.trace.statsTableName";
public static final String TRACING_CUSTOM_ANNOTATION_ATTRIB_PREFIX = "phoenix.trace.custom.annotation.";
public static final String TRACING_ENABLED = "phoenix.trace.enabled";
public static final String TRACING_BATCH_SIZE = "phoenix.trace.batchSize";
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
index b39fb788a61..b4c77da3eaf 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
@@ -101,11 +101,7 @@
import static org.apache.phoenix.query.QueryServices.TABLE_LEVEL_METRICS_ENABLED;
import static org.apache.phoenix.query.QueryServices.THREAD_POOL_SIZE_ATTRIB;
import static org.apache.phoenix.query.QueryServices.THREAD_TIMEOUT_MS_ATTRIB;
-import static org.apache.phoenix.query.QueryServices.TRACING_BATCH_SIZE;
import static org.apache.phoenix.query.QueryServices.TRACING_ENABLED;
-import static org.apache.phoenix.query.QueryServices.TRACING_STATS_TABLE_NAME_ATTRIB;
-import static org.apache.phoenix.query.QueryServices.TRACING_THREAD_POOL_SIZE;
-import static org.apache.phoenix.query.QueryServices.TRACING_TRACE_BUFFER_SIZE;
import static org.apache.phoenix.query.QueryServices.TRANSACTIONS_ENABLED;
import static org.apache.phoenix.query.QueryServices.UPLOAD_BINARY_DATA_TYPE_ENCODING;
import static org.apache.phoenix.query.QueryServices.USE_BYTE_BASED_REGEX_ATTRIB;
@@ -129,7 +125,6 @@
import org.apache.phoenix.schema.PTable.ImmutableStorageScheme;
import org.apache.phoenix.schema.PTable.QualifierEncodingScheme;
import org.apache.phoenix.schema.PTableRefFactory;
-import org.apache.phoenix.trace.util.Tracing;
import org.apache.phoenix.transaction.TransactionFactory;
import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.ReadOnlyProps;
@@ -254,9 +249,6 @@ public class QueryServicesOptions {
/**
* Configuration key to overwrite the tablename that should be used as the target table
*/
- public static final String DEFAULT_TRACING_STATS_TABLE_NAME = "SYSTEM.TRACING_STATS";
- public static final String DEFAULT_TRACING_FREQ = Tracing.Frequency.NEVER.getKey();
- public static final double DEFAULT_TRACING_PROBABILITY_THRESHOLD = 0.05;
public static final int DEFAULT_STATS_UPDATE_FREQ_MS = 15 * 60000; // 15min
public static final int DEFAULT_STATS_GUIDEPOST_PER_REGION = 0; // Uses guidepost width by default
@@ -494,8 +486,6 @@ public static QueryServicesOptions withDefaults() {
.setIfUnset(AUTO_UPGRADE_ENABLED, DEFAULT_AUTO_UPGRADE_ENABLED)
.setIfUnset(UPLOAD_BINARY_DATA_TYPE_ENCODING, DEFAULT_UPLOAD_BINARY_DATA_TYPE_ENCODING)
.setIfUnset(TRACING_ENABLED, DEFAULT_TRACING_ENABLED)
- .setIfUnset(TRACING_BATCH_SIZE, DEFAULT_TRACING_BATCH_SIZE)
- .setIfUnset(TRACING_THREAD_POOL_SIZE, DEFAULT_TRACING_THREAD_POOL_SIZE)
.setIfUnset(STATS_COLLECTION_ENABLED, DEFAULT_STATS_COLLECTION_ENABLED)
.setIfUnset(USE_STATS_FOR_PARALLELIZATION, DEFAULT_USE_STATS_FOR_PARALLELIZATION)
.setIfUnset(USE_STATS_FOR_PARALLELIZATION, DEFAULT_USE_STATS_FOR_PARALLELIZATION)
@@ -731,23 +721,6 @@ public QueryServicesOptions setTracingEnabled(boolean enable) {
return this;
}
- public int getTracingThreadPoolSize() {
- return config.getInt(TRACING_THREAD_POOL_SIZE, DEFAULT_TRACING_THREAD_POOL_SIZE);
- }
-
- public int getTracingBatchSize() {
- return config.getInt(TRACING_BATCH_SIZE, DEFAULT_TRACING_BATCH_SIZE);
- }
-
- public int getTracingTraceBufferSize() {
- return config.getInt(TRACING_TRACE_BUFFER_SIZE, DEFAULT_TRACING_TRACE_BUFFER_SIZE);
- }
-
- public String getTableName() {
- return config.get(TRACING_STATS_TABLE_NAME_ATTRIB, DEFAULT_TRACING_STATS_TABLE_NAME);
- }
-
-
public boolean isGlobalMetricsEnabled() {
return config.getBoolean(GLOBAL_METRICS_ENABLED, DEFAULT_IS_GLOBAL_METRICS_ENABLED);
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/UpdateStatisticsTool.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/UpdateStatisticsTool.java
index ffe7ed5f5da..286592b1943 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/UpdateStatisticsTool.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/UpdateStatisticsTool.java
@@ -41,7 +41,6 @@
import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
-import org.apache.htrace.SpanReceiver;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.mapreduce.util.ConnectionUtil;
import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
@@ -53,6 +52,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.opentelemetry.api.trace.Span;
+
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY;
import java.nio.charset.StandardCharsets;
@@ -215,7 +216,7 @@ private void configureJob() throws Exception {
TableMapReduceUtil.addDependencyJars(job);
TableMapReduceUtil.addDependencyJarsForClasses(job.getConfiguration(),
PhoenixConnection.class, Chronology.class, CharStream.class,
- SpanReceiver.class, Gauge.class, MetricRegistriesImpl.class);
+ Span.class, Gauge.class, MetricRegistriesImpl.class);
LOGGER.info("UpdateStatisticsTool running for: " + tableName
+ " on snapshot: " + snapshotName + " with restore dir: " + restoreDir);
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/NullScope.java
similarity index 70%
rename from phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java
rename to phoenix-core/src/main/java/org/apache/phoenix/trace/NullScope.java
index 0d2def3e66d..919c0b70b6f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/trace/PhoenixTagImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/trace/NullScope.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -7,7 +7,7 @@
* "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
+ * 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,
@@ -17,13 +17,17 @@
*/
package org.apache.phoenix.trace;
-import org.apache.hadoop.metrics2.MetricsTag;
+import io.opentelemetry.context.Scope;
/**
- * Simple Tag implementation for testing
+ * Facade class that implements AutoCloseable, but does not interact with tracing in any way
*/
-public class PhoenixTagImpl extends MetricsTag {
- public PhoenixTagImpl(String name, String description, String value) {
- super(new MetricsInfoImpl(name, description), value);
+public class NullScope implements Scope {
+
+ public static final NullScope INSTANCE = new NullScope();
+
+ @Override
+ public void close() {
}
-}
\ No newline at end of file
+
+}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java b/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
deleted file mode 100644
index 2428ddd76ff..00000000000
--- a/phoenix-core/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-package org.apache.phoenix.trace;
-
-import static org.apache.phoenix.metrics.MetricInfo.ANNOTATION;
-import static org.apache.phoenix.metrics.MetricInfo.DESCRIPTION;
-import static org.apache.phoenix.metrics.MetricInfo.END;
-import static org.apache.phoenix.metrics.MetricInfo.HOSTNAME;
-import static org.apache.phoenix.metrics.MetricInfo.PARENT;
-import static org.apache.phoenix.metrics.MetricInfo.SPAN;
-import static org.apache.phoenix.metrics.MetricInfo.START;
-import static org.apache.phoenix.metrics.MetricInfo.TAG;
-import static org.apache.phoenix.metrics.MetricInfo.TRACE;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.commons.configuration2.SubsetConfiguration;
-import org.apache.hadoop.hbase.HBaseConfiguration;
-import org.apache.hadoop.hbase.TableNotDisabledException;
-import org.apache.hadoop.metrics2.AbstractMetric;
-import org.apache.hadoop.metrics2.MetricsRecord;
-import org.apache.hadoop.metrics2.MetricsSink;
-import org.apache.hadoop.metrics2.MetricsTag;
-import org.apache.phoenix.compile.MutationPlan;
-import org.apache.phoenix.execute.MutationState;
-import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
-import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
-import org.apache.phoenix.metrics.MetricInfo;
-import org.apache.phoenix.metrics.Metrics;
-import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.schema.TableNotFoundException;
-import org.apache.phoenix.trace.util.Tracing;
-import org.apache.phoenix.util.PhoenixRuntime;
-import org.apache.phoenix.util.QueryUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.phoenix.thirdparty.com.google.common.annotations.VisibleForTesting;
-import org.apache.phoenix.thirdparty.com.google.common.base.Joiner;
-
-/**
- * Write the metrics to a phoenix table.
- * Generally, this class is instantiated via hadoop-metrics2 property files.
- * Specifically, you would create this class by adding the following to
- * by
- * This would actually be set as:
- * [prefix].sink.[some instance name].class=org.apache.phoenix.trace.PhoenixMetricsSink
- * , where prefix is either:
- *
- *
"phoenix", for the client
- *
"hbase", for the server
- *
- * and
- * some instance name is just any unique name, so properties can be differentiated if
- * there are multiple sinks of the same type created
- */
-public class PhoenixMetricsSink implements MetricsSink {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(PhoenixMetricsSink.class);
-
- private static final String VARIABLE_VALUE = "?";
-
- private static final Joiner COLUMN_JOIN = Joiner.on(".");
- static final String TAG_FAMILY = "tags";
- /**
- * Count of the number of tags we are storing for this row
- */
- static final String TAG_COUNT = COLUMN_JOIN.join(TAG_FAMILY, "count");
-
- static final String ANNOTATION_FAMILY = "annotations";
- static final String ANNOTATION_COUNT = COLUMN_JOIN.join(ANNOTATION_FAMILY, "count");
-
- /**
- * Join strings on a comma
- */
- private static final Joiner COMMAS = Joiner.on(',');
-
- private Connection conn;
-
- private String table;
-
- public PhoenixMetricsSink() {
- LOGGER.info("Writing tracing metrics to phoenix table");
-
- }
-
- @Override
- public void init(SubsetConfiguration config) {
- Metrics.markSinkInitialized();
- LOGGER.info("Phoenix tracing writer started");
- }
-
- /**
- * Initialize this only when we need it
- */
- private void lazyInitialize() {
- synchronized (this) {
- if (this.conn != null) {
- return;
- }
- try {
- // create the phoenix connection
- Properties props = new Properties();
- props.setProperty(QueryServices.TRACING_FREQ_ATTRIB,
- Tracing.Frequency.NEVER.getKey());
- org.apache.hadoop.conf.Configuration conf = HBaseConfiguration.create();
- Connection conn = QueryUtil.getConnectionOnServer(props, conf);
- // enable bulk loading when we have enough data
- conn.setAutoCommit(true);
-
- String tableName =
- conf.get(QueryServices.TRACING_STATS_TABLE_NAME_ATTRIB,
- QueryServicesOptions.DEFAULT_TRACING_STATS_TABLE_NAME);
-
- initializeInternal(conn, tableName);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- private void initializeInternal(Connection conn, String tableName) throws SQLException {
- this.conn = conn;
- // ensure that the target table already exists
- if (!traceTableExists(conn, tableName)) {
- createTable(conn, tableName);
- }
- this.table = tableName;
- }
-
- private boolean traceTableExists(Connection conn, String traceTableName) throws SQLException {
- try {
- PhoenixRuntime.getTable(conn, traceTableName);
- return true;
- } catch (TableNotFoundException e) {
- return false;
- }
- }
-
- /**
- * Used for TESTING ONLY
- * Initialize the connection and setup the table to use the
- * {@link org.apache.phoenix.query.QueryServicesOptions#DEFAULT_TRACING_STATS_TABLE_NAME}
- *
- * @param conn to store for upserts and to create the table (if necessary)
- * @param tableName TODO
- * @throws SQLException if any phoenix operation fails
- */
- @VisibleForTesting
- public void initForTesting(Connection conn, String tableName) throws SQLException {
- initializeInternal(conn, tableName);
- }
-
- /**
- * Create a stats table with the given name. Stores the name for use later when creating upsert
- * statements
- *
- * @param conn connection to use when creating the table
- * @param table name of the table to create
- * @throws SQLException if any phoenix operations fails
- */
- private void createTable(Connection conn, String table) throws SQLException {
- // only primary-key columns can be marked non-null
- String ddl =
- "create table if not exists " + table + "( " +
- TRACE.columnName + " bigint not null, " +
- PARENT.columnName + " bigint not null, " +
- SPAN.columnName + " bigint not null, " +
- DESCRIPTION.columnName + " varchar, " +
- START.columnName + " bigint, " +
- END.columnName + " bigint, " +
- HOSTNAME.columnName + " varchar, " +
- TAG_COUNT + " smallint, " +
- ANNOTATION_COUNT + " smallint" +
- " CONSTRAINT pk PRIMARY KEY (" + TRACE.columnName + ", "
- + PARENT.columnName + ", " + SPAN.columnName + "))\n" +
- // We have a config parameter that can be set so that tables are
- // transactional by default. If that's set, we still don't want these system
- // tables created as transactional tables, make these table non
- // transactional
- PhoenixDatabaseMetaData.TRANSACTIONAL + "=" + Boolean.FALSE;
- PreparedStatement stmt = conn.prepareStatement(ddl);
- stmt.execute();
- }
-
- @Override
- public void flush() {
- try {
- this.conn.commit();
- } catch (SQLException e) {
- LOGGER.error("Failed to commit changes to table", e);
- }
- }
-
- /**
- * Add a new metric record to be written.
- *
- * @param record
- */
- @Override
- public void putMetrics(MetricsRecord record) {
- // its not a tracing record, we are done. This could also be handled by filters, but safer
- // to do it here, in case it gets misconfigured
- if (!record.name().startsWith(TracingUtils.METRIC_SOURCE_KEY)) {
- return;
- }
-
- // don't initialize until we actually have something to write
- lazyInitialize();
-
- String stmt = "UPSERT INTO " + table + " (";
- // drop it into the queue of things that should be written
- List keys = new ArrayList();
- List