From 6c83b74137a077515037fbe412858c99b34869fd Mon Sep 17 00:00:00 2001 From: Yurii Palamarchuk Date: Fri, 6 Mar 2026 16:11:12 +0100 Subject: [PATCH 1/4] Fix content --- .../metrics-and-monitoring.mdx | 4 +++- .../_mdx/(multi-page)/upgrading/version-number.mdx | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/operational-management/metrics-and-monitoring.mdx b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/operational-management/metrics-and-monitoring.mdx index 4393795d82aa..88f8957c91fe 100644 --- a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/operational-management/metrics-and-monitoring.mdx +++ b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/operational-management/metrics-and-monitoring.mdx @@ -5,7 +5,7 @@ description: "HBase metrics system configuration, JMX monitoring, master and Reg ## HBase Metrics -HBase emits metrics which adhere to the [Hadoop Metrics](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/Metrics.html) API. Starting with HBase 0.95[^1], HBase is configured to emit a default set of metrics with a default sampling period of every 10 seconds. You can use HBase metrics in conjunction with Ganglia. You can also filter which metrics are emitted and extend the metrics framework to capture custom metrics appropriate for your environment. +HBase emits metrics which adhere to the [Hadoop Metrics](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/Metrics.html) API. Starting with HBase 0.95 [^5], HBase is configured to emit a default set of metrics with a default sampling period of every 10 seconds. You can use HBase metrics in conjunction with Ganglia. You can also filter which metrics are emitted and extend the metrics framework to capture custom metrics appropriate for your environment. ### Metric Setup @@ -601,3 +601,5 @@ The format of Archived Storefile Size is NNN(MMM). NNN is the total Storefile si **_Empty Snapshot Storfile Stats Example_** ![empty snapshots](/docs-images/empty-snapshots.png) + +[^5]: The Metrics system was redone in HBase 0.96. See Migration to the New Metrics Hotness – Metrics2 by Elliot Clark for detail. diff --git a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx index 21293d61f043..52e092512d70 100644 --- a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx +++ b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx @@ -84,17 +84,17 @@ In addition to the usual API versioning considerations HBase has other compatibi #### Summary [!toc] -- A patch upgrade is a drop-in replacement. Any change that is not Java binary and source compatible would not be allowed. Downgrading versions within patch releases may not be compatible. [^2] +- A patch upgrade is a drop-in replacement. Any change that is not Java binary and source compatible would not be allowed.[^2] Downgrading versions within patch releases may not be compatible. - A minor upgrade requires no application/client code modification. Ideally it would be a drop-in replacement but client code, coprocessors, filters, etc might have to be recompiled if new jars are used. - A major upgrade allows the HBase community to make breaking changes. -#### Compatibility Matrix: [!toc] +#### Compatibility Matrix: [^3] [!toc] | | Major | Minor | Patch | | ----------------------------------------- | :----: | :---: | :---: | | Client-Server wire Compatibility | N | Y | Y | | Server-Server Compatibility | N | Y | Y | -| File Format Compatibility | N [^1] | Y | Y | +| File Format Compatibility | N [^4] | Y | Y | | Client API Compatibility | N | Y | Y | | Client Binary Compatibility | N | N | Y | | **Server-Side Limited API Compatibility** | | | | @@ -145,6 +145,10 @@ All classes annotated with InterfaceAudience.Private or all classes that do not When we say two HBase versions are compatible, we mean that the versions are wire and binary compatible. Compatible HBase versions means that clients can talk to compatible but differently versioned servers. It means too that you can just swap out the jars of one version and replace them with the jars of another, compatible version and all will just work. Unless otherwise specified, HBase point versions are (mostly) binary compatible. You can safely do rolling upgrades between binary compatible versions; i.e. across maintenance releases: e.g. from 1.4.4 to 1.4.6. See "Does compatibility between versions also mean binary compatibility?" discussion on the HBase dev mailing list. -[^1]: Running an offline upgrade tool without downgrade might be needed. We will typically only support migrating data from major version X to major version X+1. +[^1]: See 'Source Compatibility' https://blogs.oracle.com/darcy/entry/kinds_of_compatibility [^2]: See http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html. + +[^3]: Note that this indicates what could break, not that it will break. We will/should add specifics in our release notes. + +[^4]: Running an offline upgrade tool without downgrade might be needed. We will typically only support migrating data from major version X to major version X+1. From c60fdbb5ba380bdce891397e67cb0793e1bf0b16 Mon Sep 17 00:00:00 2001 From: Yurii Palamarchuk Date: Fri, 6 Mar 2026 16:22:47 +0100 Subject: [PATCH 2/4] Add tests --- hbase-website/README.md | 5 + .../(multi-page)/upgrading/version-number.mdx | 2 +- .../unit-tests/validate-references.test.ts | 92 +++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 hbase-website/unit-tests/validate-references.test.ts diff --git a/hbase-website/README.md b/hbase-website/README.md index 400d4d8146f9..a67a85699757 100644 --- a/hbase-website/README.md +++ b/hbase-website/README.md @@ -322,6 +322,11 @@ This starts a local development server with: 2. Add the new file to the relevant `meta.json` in the same section folder so it appears in navigation. 3. Import the page into `app/pages/_docs/docs/_mdx/single-page/index.mdx` and add an `#` header so it renders in the single-page docs. +> **Important:** All heading IDs and all footnote reference IDs must be **unique across every multi-page MDX file**. This is because all files are combined into a single page (see `single-page/index.mdx`), so any duplicate ID would collide in the combined document. There are automated unit tests that enforce both constraints — `unit-tests/validate-headings.test.ts` for heading IDs and `unit-tests/validate-references.test.ts` for footnote reference IDs. +> +> - **Headings**: Use an explicit `[#page-specific-id]` anchor suffix on any heading whose auto-generated slug would clash with a heading in another file. For example: `## Overview [#my-topic-overview]`. +> - **Footnotes**: Use page-specific numeric or named identifiers so they remain unique globally. For example, instead of `[^1]` in every file, simply continue the global numbering (e.g. if existing files already use `[^1]`–`[^5]`, start at `[^6]` in a new file). + **Update content:** - Edit the appropriate `.md` or `.json` file diff --git a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx index 52e092512d70..5ba71082f0da 100644 --- a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx +++ b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx @@ -145,7 +145,7 @@ All classes annotated with InterfaceAudience.Private or all classes that do not When we say two HBase versions are compatible, we mean that the versions are wire and binary compatible. Compatible HBase versions means that clients can talk to compatible but differently versioned servers. It means too that you can just swap out the jars of one version and replace them with the jars of another, compatible version and all will just work. Unless otherwise specified, HBase point versions are (mostly) binary compatible. You can safely do rolling upgrades between binary compatible versions; i.e. across maintenance releases: e.g. from 1.4.4 to 1.4.6. See "Does compatibility between versions also mean binary compatibility?" discussion on the HBase dev mailing list. -[^1]: See 'Source Compatibility' https://blogs.oracle.com/darcy/entry/kinds_of_compatibility +[^1]: See 'Source Compatibility' https://blogs.oracle.com/darcy/entry/kinds_of_compatibility [^2]: See http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html. diff --git a/hbase-website/unit-tests/validate-references.test.ts b/hbase-website/unit-tests/validate-references.test.ts new file mode 100644 index 000000000000..bf66d79e85c9 --- /dev/null +++ b/hbase-website/unit-tests/validate-references.test.ts @@ -0,0 +1,92 @@ +// +// 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. +// + +import { describe, it, expect } from "vitest"; +import fs from "node:fs"; +import path from "node:path"; + +const MULTI_PAGE_DIR = path.join(process.cwd(), "app/pages/_docs/docs/_mdx/(multi-page)"); + +function collectMdxFiles(dir: string): string[] { + const results: string[] = []; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + results.push(...collectMdxFiles(fullPath)); + } else if (entry.isFile() && entry.name.endsWith(".mdx")) { + results.push(fullPath); + } + } + return results; +} + +/** Extract all footnote definition IDs (e.g. [^1]:, [^note]:) from a file. */ +function parseFootnoteIds(content: string): string[] { + const re = /^\[\^([^\]]+)\]:/gm; + const ids: string[] = []; + let m: RegExpExecArray | null; + while ((m = re.exec(content)) !== null) { + ids.push(m[1]); + } + return ids; +} + +describe("MDX Footnote Reference Uniqueness Validation", () => { + it("should not have duplicate footnote reference IDs across all multi-page documentation files", () => { + const files = collectMdxFiles(MULTI_PAGE_DIR); + + // Map of footnote ID -> array of relative file paths that define it + const idToFiles = new Map(); + + for (const filePath of files) { + const content = fs.readFileSync(filePath, "utf-8"); + const ids = parseFootnoteIds(content); + const relPath = path.relative(process.cwd(), filePath); + + for (const id of ids) { + if (!idToFiles.has(id)) { + idToFiles.set(id, []); + } + idToFiles.get(id)!.push(relPath); + } + } + + const duplicates = Array.from(idToFiles.entries()) + .filter(([, filePaths]) => filePaths.length > 1) + .map(([id, filePaths]) => ({ id, filePaths })); + + if (duplicates.length > 0) { + console.error("\n❌ Duplicate footnote reference IDs found across different files:\n"); + + duplicates.forEach(({ id, filePaths }) => { + console.error(` Reference ID: "[^${id}]"`); + console.error(` Defined in ${filePaths.length} files:\n`); + filePaths.forEach((f) => console.error(` • ${f}`)); + console.error(); + }); + + console.error( + "💡 To fix: Footnote IDs must be unique across all multi-page docs because\n" + + " they are combined into a single page. Rename conflicting references to\n" + + " use unique identifiers, e.g. [^1] → [^version-number-1].\n" + ); + } + + expect(duplicates.length).toBe(0); + }); +}); From 2e8f1ee06288789fd887b88fcfe1b4418fa4375d Mon Sep 17 00:00:00 2001 From: Yurii Palamarchuk Date: Fri, 6 Mar 2026 16:29:21 +0100 Subject: [PATCH 3/4] Fix test --- hbase-website/unit-tests/validate-headings.test.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hbase-website/unit-tests/validate-headings.test.ts b/hbase-website/unit-tests/validate-headings.test.ts index 6fd39dc782f5..c8e6955bf6a4 100644 --- a/hbase-website/unit-tests/validate-headings.test.ts +++ b/hbase-website/unit-tests/validate-headings.test.ts @@ -99,9 +99,17 @@ describe("MDX Heading ID Uniqueness Validation", () => { }); } + // IDs that are auto-generated by the markdown processor and cannot be + // overridden by authors. "footnote-label" is emitted by the footnotes + // plugin for every page that contains footnotes; it is expected to appear + // in multiple pages and does not cause a collision problem in practice + // because the single-page build suppresses the per-page footnote sections. + const IGNORED_IDS = new Set(["footnote-label"]); + // Find IDs that appear in multiple different pages const duplicates = Array.from(idToPages.entries()) - .filter(([, occurrences]) => { + .filter(([id, occurrences]) => { + if (IGNORED_IDS.has(id)) return false; // Check if this ID appears in multiple DIFFERENT pages const uniquePages = new Set(occurrences.map((o) => o.url)); return uniquePages.size > 1; From 02d01f9c8b4d45e1da3ff6f558b67ae1924a1594 Mon Sep 17 00:00:00 2001 From: Yurii Palamarchuk Date: Fri, 6 Mar 2026 16:55:47 +0100 Subject: [PATCH 4/4] Fix link --- .../_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx index 5ba71082f0da..424ff509ffd9 100644 --- a/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx +++ b/hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/upgrading/version-number.mdx @@ -145,7 +145,7 @@ All classes annotated with InterfaceAudience.Private or all classes that do not When we say two HBase versions are compatible, we mean that the versions are wire and binary compatible. Compatible HBase versions means that clients can talk to compatible but differently versioned servers. It means too that you can just swap out the jars of one version and replace them with the jars of another, compatible version and all will just work. Unless otherwise specified, HBase point versions are (mostly) binary compatible. You can safely do rolling upgrades between binary compatible versions; i.e. across maintenance releases: e.g. from 1.4.4 to 1.4.6. See "Does compatibility between versions also mean binary compatibility?" discussion on the HBase dev mailing list. -[^1]: See 'Source Compatibility' https://blogs.oracle.com/darcy/entry/kinds_of_compatibility +[^1]: See 'Source Compatibility' https://wiki.openjdk.org/spaces/csr/pages/32342052/Kinds+of+Compatibility [^2]: See http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html.