technik: Volltext-Indizes von press_releases in eine eigene Suchtabelle auslagern
Ein FULLTEXT-Index zwingt MySQL bei JEDEM ADD COLUMN auf ALGORITHM=COPY. Auf press_releases (>1 GB) bedeutet das einen vollständigen Rebuild, während dessen kein Schreibzugriff möglich ist — im August hat genau das die Seite zum Stehen gebracht, weil die wartenden Requests PHP-FPM-Worker und DB-Verbindungen belegten. Die durchsuchbaren Felder liegen jetzt gespiegelt in `press_release_search`, die die Indizes trägt. Ihr Schema ist per Konstruktion stabil und wird nie erweitert; neue Felder gehören nach press_releases, wo sie ohne Volltext-Index Millisekunden kosten. Synchron hält sie ein Observer (alle Schreibzugriffe laufen über Eloquent, auch der Importer), reparieren lässt sie sich mit press-releases:reindex-search. Der Umstieg ist über mehrere Migrationen geteilt und schaltet erst um, wenn press_releases seine Indizes verloren hat — bis dahin sucht die Anwendung unverändert weiter. Die Drop-Migration verweigert den Dienst, solange der Suchindex unvollständig ist, und verwirft die gecachte Umschalt-Prüfung: Stünde dort noch der alte Stand, setzte der Rückfallpfad sein MATCH() auf einen soeben entfernten Index ab (MySQL-Fehler 1191) und jede Suche endete im 500er. Dazu die betriebliche Absicherung: - DB_LOCK_WAIT_TIMEOUT (Default 10 s) statt MySQLs einem Jahr. Requests scheitern bei einer laufenden Schemaänderung nach Sekunden, statt sich aufzustauen, bis keine Verbindung mehr frei ist. - Sessions und Cache nach Redis, damit eine blockierte MySQL-Tabelle nicht die gesamte Anwendung mitreißt. - db:online-alter als Notausgang (pt-online-schema-change), falls eine der kleinen FULLTEXT-Tabellen doch einmal groß wird. Percona-Toolkit ist bewusst nicht Teil des Standard-Setups. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9afbedddeb
commit
f8728c5bca
14 changed files with 1076 additions and 5 deletions
|
|
@ -11,6 +11,7 @@ use App\Models\Company;
|
|||
use App\Models\Contact;
|
||||
use App\Models\KiAudit;
|
||||
use App\Models\PressRelease;
|
||||
use App\Models\PressReleaseSearchIndex;
|
||||
use App\Models\User;
|
||||
use App\Services\Admin\AdminPerformanceCache;
|
||||
use App\Services\PressRelease\BlacklistViolationException;
|
||||
|
|
@ -292,7 +293,10 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
$term = trim($this->search);
|
||||
$q->where(function ($q) use ($term): void {
|
||||
if ($this->supportsFullTextSearch($term)) {
|
||||
$q->whereFullText(['title', 'keywords'], $term)
|
||||
// Volltext über die Suchtabelle — press_releases selbst
|
||||
// trägt keinen Index mehr, damit neue Spalten dort ohne
|
||||
// stundenlangen Rebuild angelegt werden können.
|
||||
$q->where(fn ($inner) => PressReleaseSearchIndex::constrain($inner, ['title', 'keywords'], $term))
|
||||
->orWhereHas('company', fn ($q) => $q->whereFullText(['name', 'email', 'slug'], $term));
|
||||
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue