private void appendDeadlockStatusInformation()

in src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeProtocol.java [1924:2024]


    private void appendDeadlockStatusInformation(Session sess, String xOpen, StringBuilder errorBuf) {
        if (sess.getPropertySet().getBooleanProperty(PropertyKey.includeInnodbStatusInDeadlockExceptions).getValue() && xOpen != null
                && (xOpen.startsWith("40") || xOpen.startsWith("41")) && getStreamingData() == null) {

            TelemetrySpan span = this.session.getTelemetryHandler().startSpan(TelemetrySpanName.STMT_EXECUTE);
            try (TelemetryScope scope = span.makeCurrent()) {
                span.setAttribute(TelemetryAttribute.DB_NAME, () -> this.session.getHostInfo().getDatabase());
                span.setAttribute(TelemetryAttribute.DB_OPERATION, TelemetryAttribute.OPERATION_SHOW);
                span.setAttribute(TelemetryAttribute.DB_STATEMENT, TelemetryAttribute.OPERATION_SHOW + TelemetryAttribute.STATEMENT_SUFFIX);
                span.setAttribute(TelemetryAttribute.DB_SYSTEM, TelemetryAttribute.DB_SYSTEM_DEFAULT);
                span.setAttribute(TelemetryAttribute.DB_USER, () -> this.session.getHostInfo().getUser());
                span.setAttribute(TelemetryAttribute.THREAD_ID, () -> Thread.currentThread().getId());
                span.setAttribute(TelemetryAttribute.THREAD_NAME, () -> Thread.currentThread().getName());

                try {
                    NativePacketPayload resultPacket = sendCommand(
                            getNativeMessageBuilder().buildComQuery(getSharedSendPacket(), this.session, "SHOW ENGINE INNODB STATUS"), false, 0);

                    Resultset rs = readAllResults(-1, false, resultPacket, false, null, new ResultsetFactory(Type.FORWARD_ONLY, null));

                    int colIndex = 0;
                    Field f = null;
                    for (int i = 0; i < rs.getColumnDefinition().getFields().length; i++) {
                        f = rs.getColumnDefinition().getFields()[i];
                        if ("Status".equals(f.getName())) {
                            colIndex = i;
                            break;
                        }
                    }

                    ValueFactory<String> vf = new StringValueFactory(this.propertySet);

                    Row r;
                    if ((r = rs.getRows().next()) != null) {
                        errorBuf.append("\n\n").append(r.getValue(colIndex, vf));
                    } else {
                        errorBuf.append("\n\n").append(Messages.getString("MysqlIO.NoInnoDBStatusFound"));
                    }
                } catch (IOException | CJException ex) {
                    errorBuf.append("\n\n").append(Messages.getString("MysqlIO.InnoDBStatusFailed")).append("\n\n").append(Util.stackTraceToString(ex));
                }
            } catch (Throwable t) {
                span.setError(t);
                throw t;
            } finally {
                span.end();
            }
        }

        if (sess.getPropertySet().getBooleanProperty(PropertyKey.includeThreadDumpInDeadlockExceptions).getValue()) {
            errorBuf.append("\n\n*** Java threads running at time of deadlock ***\n\n");

            ThreadMXBean threadMBean = ManagementFactory.getThreadMXBean();
            long[] threadIds = threadMBean.getAllThreadIds();

            ThreadInfo[] threads = threadMBean.getThreadInfo(threadIds, Integer.MAX_VALUE);
            List<ThreadInfo> activeThreads = new ArrayList<>();

            for (ThreadInfo info : threads) {
                if (info != null) {
                    activeThreads.add(info);
                }
            }

            for (ThreadInfo threadInfo : activeThreads) {
                // "Thread-60" daemon prio=1 tid=0x093569c0 nid=0x1b99 in Object.wait()

                errorBuf.append('"').append(threadInfo.getThreadName()).append("\" tid=").append(threadInfo.getThreadId()).append(" ")
                        .append(threadInfo.getThreadState());

                if (threadInfo.getLockName() != null) {
                    errorBuf.append(" on lock=").append(threadInfo.getLockName());
                }
                if (threadInfo.isSuspended()) {
                    errorBuf.append(" (suspended)");
                }
                if (threadInfo.isInNative()) {
                    errorBuf.append(" (running in native)");
                }

                StackTraceElement[] stackTrace = threadInfo.getStackTrace();

                if (stackTrace.length > 0) {
                    errorBuf.append(" in ");
                    errorBuf.append(stackTrace[0].getClassName()).append(".");
                    errorBuf.append(stackTrace[0].getMethodName()).append("()");
                }

                errorBuf.append("\n");

                if (threadInfo.getLockOwnerName() != null) {
                    errorBuf.append("\t owned by ").append(threadInfo.getLockOwnerName()).append(" Id=").append(threadInfo.getLockOwnerId()).append("\n");
                }

                for (int j = 0; j < stackTrace.length; j++) {
                    StackTraceElement ste = stackTrace[j];
                    errorBuf.append("\tat ").append(ste.toString()).append("\n");
                }
            }
        }
    }